From arigo at codespeak.net Sat Oct 1 00:45:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 00:45:27 +0200 (CEST) Subject: [pypy-svn] r18030 - pypy/dist/pypy/module/sys Message-ID: <20050930224527.54D8827BBE@code1.codespeak.net> Author: arigo Date: Sat Oct 1 00:45:26 2005 New Revision: 18030 Modified: pypy/dist/pypy/module/sys/version.py Log: Show the svn revision number in sys.version. Useful when people paste session logs of pypy-c to pypy-dev. Modified: pypy/dist/pypy/module/sys/version.py ============================================================================== --- pypy/dist/pypy/module/sys/version.py (original) +++ pypy/dist/pypy/module/sys/version.py Sat Oct 1 00:45:26 2005 @@ -23,13 +23,14 @@ return space.wrap(CPYTHON_VERSION) def get_version(space): - return space.wrap("%d.%d.%d (pypy %d.%d.%d build)" % ( + return space.wrap("%d.%d.%d (pypy %d.%d.%d build %d)" % ( CPYTHON_VERSION[0], CPYTHON_VERSION[1], CPYTHON_VERSION[2], PYPY_VERSION[0], PYPY_VERSION[1], - PYPY_VERSION[2])) + PYPY_VERSION[2], + svn_revision())) def get_hexversion(space): return space.wrap(tuple2hex(CPYTHON_VERSION)) From pedronis at codespeak.net Sat Oct 1 02:01:38 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 02:01:38 +0200 (CEST) Subject: [pypy-svn] r18031 - pypy/dist/pypy/translator/c Message-ID: <20051001000138.8B50C27BC7@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 02:01:36 2005 New Revision: 18031 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/pyobj.py pypy/dist/pypy/translator/c/support.py Log: print -> logging Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Sat Oct 1 02:01:36 2005 @@ -9,6 +9,7 @@ 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.support import log # ____________________________________________________________ @@ -162,7 +163,7 @@ lst = ['%s: %d' % keyvalue for keyvalue in self.containerstats.items()] lst.sort() - print '%8d nodes [ %s ]' % (i, ' '.join(lst)) + log.event('%8d nodes [ %s ]' % (i, ' '.join(lst))) i = self.completedcontainers if show_progress: show_i = (i//1000 + 1) * 1000 Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Sat Oct 1 02:01:36 2005 @@ -4,6 +4,7 @@ from pypy.objspace.flow.model import Variable, Constant from pypy.translator.gensupp import builtin_base +from pypy.translator.c.support import log from pypy.rpython.rarithmetic import r_int, r_uint from pypy.rpython.lltype import pyobjectptr, LowLevelType @@ -153,7 +154,7 @@ func.func_globals.get('__name__', '?'), func.func_code.co_firstlineno, func.__name__) - print warning, printable_name + log.WARNING("%s %s" % (warning, printable_name)) name = self.uniquename('gskippedfunc_' + func.__name__) self.initcode.append('def %s(*a,**k):' % name) self.initcode.append(' raise NotImplementedError') @@ -311,14 +312,14 @@ # XXX some __NAMES__ are important... nicer solution sought #raise Exception, "unexpected name %r in class %s"%(key, cls) if isinstance(value, staticmethod) and value.__get__(1) not in self.translator.flowgraphs and self.translator.frozen: - print value + log.WARNING(str(value)) continue if isinstance(value, classmethod): doc = value.__get__(cls).__doc__ if doc and doc.lstrip().startswith("NOT_RPYTHON"): continue if isinstance(value, FunctionType) and value not in self.translator.flowgraphs and self.translator.frozen: - print value + log.WARNING(str(value)) continue if key in ignore: continue Modified: pypy/dist/pypy/translator/c/support.py ============================================================================== --- pypy/dist/pypy/translator/c/support.py (original) +++ pypy/dist/pypy/translator/c/support.py Sat Oct 1 02:01:36 2005 @@ -134,3 +134,10 @@ code.insert(0, '{ %s = %s;' % (tmpdecl, starting)) code[-1] = '%s = tmp; }' % (srcchain[-2],) yield ' '.join(code) + +# logging + +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("c") +py.log.setconsumer("c", ansi_log) From pedronis at codespeak.net Sat Oct 1 02:12:26 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 02:12:26 +0200 (CEST) Subject: [pypy-svn] r18032 - pypy/dist/pypy/translator/backendopt Message-ID: <20051001001226.B0EFB27BC9@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 02:12:23 2005 New Revision: 18032 Added: pypy/dist/pypy/translator/backendopt/support.py (contents, props changed) Modified: pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/malloc.py Log: print -> logging Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Sat Oct 1 02:12:23 2005 @@ -9,6 +9,7 @@ from pypy.rpython.lltype import Bool, typeOf from pypy.rpython import rmodel from pypy.translator.backendopt import sparsemat +from pypy.translator.backendopt.support import log BASE_INLINE_THRESHOLD = 32.4 # just enough to inline add__Int_Int() # and just small enough to prevend inlining of some rlist functions. @@ -336,18 +337,16 @@ break # finished heappop(fiboheap) - print 'Inlining %7.2f %50s' % (weight, graph.name) + log.inlining('%7.2f %50s' % (weight, graph.name)) for parentgraph in callers[graph]: if parentgraph == graph: continue - print '\t\t-> in %s...' % parentgraph.name, sys.stdout.flush() try: res = bool(inline_function(translator, graph, parentgraph)) except CannotInline: couldnt_inline[graph] = True res = CannotInline - print res if res is True: # the parentgraph should now contain all calls that were # done by 'graph' Modified: pypy/dist/pypy/translator/backendopt/malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/malloc.py Sat Oct 1 02:12:23 2005 @@ -3,6 +3,7 @@ from pypy.tool.unionfind import UnionFind from pypy.rpython import lltype from pypy.translator.simplify import remove_identical_vars +from pypy.translator.backendopt.support import log class LifeTime: @@ -232,6 +233,6 @@ """Iteratively remove (inline) the mallocs that can be simplified away.""" done_something = False while remove_mallocs_once(graph): - print 'simple mallocs removed in %r' % graph.name + log.malloc('simple mallocs removed in %r' % graph.name) done_something = True return done_something Added: pypy/dist/pypy/translator/backendopt/support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/backendopt/support.py Sat Oct 1 02:12:23 2005 @@ -0,0 +1,6 @@ +# logging + +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("backendopt") +py.log.setconsumer("backendopt", ansi_log) From pedronis at codespeak.net Sat Oct 1 02:27:00 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 02:27:00 +0200 (CEST) Subject: [pypy-svn] r18033 - pypy/dist/pypy/translator/c Message-ID: <20051001002700.0078C27BCC@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 02:26:59 2005 New Revision: 18033 Modified: pypy/dist/pypy/translator/c/pyobj.py Log: more info in warnings Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Sat Oct 1 02:26:59 2005 @@ -312,14 +312,14 @@ # XXX some __NAMES__ are important... nicer solution sought #raise Exception, "unexpected name %r in class %s"%(key, cls) if isinstance(value, staticmethod) and value.__get__(1) not in self.translator.flowgraphs and self.translator.frozen: - log.WARNING(str(value)) + log.WARNING("skipped staticmethod: %s" % value) continue if isinstance(value, classmethod): doc = value.__get__(cls).__doc__ if doc and doc.lstrip().startswith("NOT_RPYTHON"): continue if isinstance(value, FunctionType) and value not in self.translator.flowgraphs and self.translator.frozen: - log.WARNING(str(value)) + log.WARNING("skipped class function: %s" % value) continue if key in ignore: continue From pedronis at codespeak.net Sat Oct 1 02:33:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 02:33:59 +0200 (CEST) Subject: [pypy-svn] r18034 - pypy/dist/pypy/translator Message-ID: <20051001003359.C433E27BCE@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 02:33:58 2005 New Revision: 18034 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: print -> logging Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Sat Oct 1 02:33:58 2005 @@ -76,6 +76,10 @@ import pypy # __path__ import py.path +from pypy.tool.ansi_print import ansi_log + +log = py.log.Producer("geninterp") +py.log.setconsumer("geninterp", ansi_log) GI_VERSION = '1.1.15' # bump this for substantial changes # ____________________________________________________________ @@ -586,12 +590,12 @@ func.__name__) if self.translator.frozen: if func not in self.translator.flowgraphs: - print "NOT GENERATING", printable_name + log.WARNING("NOT GENERATING %s" % printable_name) return self.skipped_function(func) else: if (func.func_doc and func.func_doc.lstrip().startswith('NOT_RPYTHON')): - print "skipped", printable_name + log.WARNING("skipped %s" % printable_name) return self.skipped_function(func) name = self.uniquename('gfunc_' + self.trans_funcname( namehint + func.__name__)) @@ -658,8 +662,8 @@ yield 'space.setattr(%s, %s, %s)' % ( name, self.nameof(key), self.nameof(value)) except: - print >> sys.stderr, "Problem while generating %s of %r" % ( - name, instance) + log.ERROR("Problem while generating %s of %r" % ( + name, instance)) raise self.initcode.append1("%s = space.call_method(%s, '__new__', %s)" % ( name, cls, cls)) @@ -726,7 +730,7 @@ printable_name = cls.__name__ if cls.__doc__ and cls.__doc__.lstrip().startswith('NOT_RPYTHON'): #raise Exception, "%r should never be reached" % (cls,) - print "skipped class", printable_name + log.WARNING("skipped class %s" % printable_name) return self.skipped_class(cls) metaclass = "space.w_type" @@ -761,10 +765,10 @@ value = getattr(cls, key) if isinstance(value, staticmethod) and value.__get__(1) not in self.translator.flowgraphs and self.translator.frozen: - print "skipped staticmethod:", value + log.WARNING("skipped staticmethod: %s" % value) continue if isinstance(value, FunctionType) and value not in self.translator.flowgraphs and self.translator.frozen: - print "skipped function:", value + log.WARNING("skipped function: %s" % value) continue yield 'space.setattr(%s, %s, %s)' % ( From pedronis at codespeak.net Sat Oct 1 04:19:57 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 04:19:57 +0200 (CEST) Subject: [pypy-svn] r18035 - pypy/dist/pypy/tool Message-ID: <20051001021957.9E5DB27BC4@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 04:19:55 2005 New Revision: 18035 Modified: pypy/dist/pypy/tool/ansi_print.py Log: change color for info Modified: pypy/dist/pypy/tool/ansi_print.py ============================================================================== --- pypy/dist/pypy/tool/ansi_print.py (original) +++ pypy/dist/pypy/tool/ansi_print.py Sat Oct 1 04:19:55 2005 @@ -29,7 +29,7 @@ 'WARNING': ((31,), False), 'event': ((1,), True), 'ERROR': ((1, 31), False), - 'info': ((32,), False), + 'info': ((35,), False), } def __init__(self, kw_to_color={}, file=None): From pedronis at codespeak.net Sat Oct 1 04:21:05 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 04:21:05 +0200 (CEST) Subject: [pypy-svn] r18036 - pypy/dist/pypy/translator Message-ID: <20051001022105.3BD3E27BCD@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 04:21:03 2005 New Revision: 18036 Modified: pypy/dist/pypy/translator/translator.py Log: about should optinally take a file-like object Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Sat Oct 1 04:21:03 2005 @@ -132,8 +132,10 @@ self.annotator.build_types(graph, input_args_types, func) return self.annotator - def about(self, x): + def about(self, x, f=None): """Interactive debugging helper """ + if f is None: + f = sys.stdout from pypy.objspace.flow.model import Block, flatten if isinstance(x, Block): for func, graph in self.flowgraphs.items(): @@ -142,18 +144,18 @@ cls = getattr(func, 'class_', None) if cls: funcname = '%s.%s' % (cls.__name__, funcname) - print '%s is a %s in the graph of %s' % (x, + print >>f, '%s is a %s in the graph of %s' % (x, x.__class__.__name__, funcname) - print 'at %s:%d' % (func.func_globals.get('__name__', '?'), - func.func_code.co_firstlineno) + print >>f, 'at %s:%d' % (func.func_globals.get('__name__', '?'), + func.func_code.co_firstlineno) break else: - print '%s is a %s at some unknown location' % (x, - x.__class__.__name__) - print 'containing the following operations:' + print >>f, '%s is a %s at some unknown location' % (x, + x.__class__.__name__) + print >>f, 'containing the following operations:' for op in x.operations: - print " ",op - print '--end--' + print >>f, " ",op + print >>f, '--end--' return raise TypeError, "don't know about %r" % x From pedronis at codespeak.net Sat Oct 1 04:22:42 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 04:22:42 +0200 (CEST) Subject: [pypy-svn] r18037 - pypy/dist/pypy/translator Message-ID: <20051001022242.223E727BCF@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 04:22:40 2005 New Revision: 18037 Modified: pypy/dist/pypy/translator/annrpython.py Log: keep this up-to-date Modified: pypy/dist/pypy/translator/annrpython.py ============================================================================== --- pypy/dist/pypy/translator/annrpython.py (original) +++ pypy/dist/pypy/translator/annrpython.py Sat Oct 1 04:22:40 2005 @@ -55,7 +55,7 @@ def __getstate__(self): attrs = """translator pendingblocks bindings annotated links_followed - notify bookkeeper frozen policy""".split() + notify bookkeeper frozen policy added_blocks""".split() ret = self.__dict__.copy() for key, value in ret.items(): if key not in attrs: From pedronis at codespeak.net Sat Oct 1 04:31:33 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 04:31:33 +0200 (CEST) Subject: [pypy-svn] r18038 - pypy/dist/pypy/translator/tool Message-ID: <20051001023133.2A91727BD4@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 04:31:31 2005 New Revision: 18038 Modified: pypy/dist/pypy/translator/tool/graphpage.py Log: TranslatorPage should fall back to LocalizedCallGraphpPage if there are too many functions Modified: pypy/dist/pypy/translator/tool/graphpage.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphpage.py (original) +++ pypy/dist/pypy/translator/tool/graphpage.py Sat Oct 1 04:31:31 2005 @@ -264,6 +264,9 @@ return name def followlink(self, name): + if name.endswith('...'): + obj = self.object_by_name[name] + return LocalizedCallGraphPage(self.translator, obj) obj = self.object_by_name[name] if isinstance(obj, ClassDef): return ClassDefPage(self.translator, obj) @@ -274,14 +277,19 @@ """A GraphPage showing a the call graph between functions as well as the class hierarchy.""" - def graph_name(self): + def graph_name(self, huge=0): return 'translator' - def do_compute(self, dotgen): + def do_compute(self, dotgen, huge=100): translator = self.translator # show the call graph functions = translator.functions + + if len(functions) > huge: + LocalizedCallGraphPage.do_compute.im_func(self, dotgen, translator.entrypoint) + return + blocked_functions = self.get_blocked_functions(functions) highlight_functions = getattr(translator, 'highlight_functions', {}) # XXX @@ -300,7 +308,8 @@ else: kw = {} dotgen.emit_node(nameof(func), label=data, shape="box", **kw) - dotgen.emit_edge('entry', nameof(functions[0]), color="green") + if functions: + dotgen.emit_edge('entry', nameof(functions[0]), color="green") for f1, f2 in translator.callgraph.itervalues(): dotgen.emit_edge(nameof(f1), nameof(f2)) @@ -354,12 +363,6 @@ self.links[label] = 'go to its localized call graph' self.object_by_name[label] = func - def followlink(self, name): - if name.endswith('...'): - obj = self.object_by_name[name] - return LocalizedCallGraphPage(self.translator, obj) - return BaseTranslatorPage.followlink(self, name) - class ClassHierarchyPage(BaseTranslatorPage): """A GraphPage showing the class hierarchy.""" From pedronis at codespeak.net Sat Oct 1 04:34:21 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 04:34:21 +0200 (CEST) Subject: [pypy-svn] r18039 - in pypy/dist/pypy/translator: . backendopt Message-ID: <20051001023421.9B91E27BD8@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 04:34:19 2005 New Revision: 18039 Modified: pypy/dist/pypy/translator/backendopt/tailrecursion.py pypy/dist/pypy/translator/simplify.py Log: invert strange import dependecy. Was also breaking fork before rtype! Modified: pypy/dist/pypy/translator/backendopt/tailrecursion.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/tailrecursion.py (original) +++ pypy/dist/pypy/translator/backendopt/tailrecursion.py Sat Oct 1 04:34:19 2005 @@ -1,34 +1,14 @@ import sys +from pypy.translator.simplify import get_graph from pypy.translator.unsimplify import copyvar, split_block from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, last_exception from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph, flatten from pypy.annotation import model as annmodel from pypy.rpython.lltype import Bool, typeOf, FuncType, _ptr -from pypy.rpython import rmodel # this transformation is very academical -- I had too much time -def get_graph(arg, translator): - if isinstance(arg, Variable): - return None - f = arg.value - if not isinstance(f, _ptr): - return None - try: - callable = f._obj._callable - #external function calls don't have a real graph - if getattr(callable, "suggested_primitive", False): - return None - if callable in translator.flowgraphs: - return translator.flowgraphs[callable] - except AttributeError, KeyError: - pass - try: - return f._obj.graph - except AttributeError: - return None - def _remove_tail_call(translator, graph, block): print "removing tail call" assert len(block.exits) == 1 Modified: pypy/dist/pypy/translator/simplify.py ============================================================================== --- pypy/dist/pypy/translator/simplify.py (original) +++ pypy/dist/pypy/translator/simplify.py Sat Oct 1 04:34:19 2005 @@ -9,7 +9,29 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import last_exception from pypy.objspace.flow.model import checkgraph, traverse, mkentrymap -from pypy.translator.backendopt.tailrecursion import get_graph + +def get_graph(arg, translator): + if isinstance(arg, Variable): + return None + f = arg.value + from pypy.rpython import lltype + if not isinstance(f, lltype._ptr): + return None + try: + callable = f._obj._callable + #external function calls don't have a real graph + if getattr(callable, "suggested_primitive", False): + return None + if callable in translator.flowgraphs: + return translator.flowgraphs[callable] + except AttributeError, KeyError: + pass + try: + return f._obj.graph + except AttributeError: + return None + + # ____________________________________________________________ def eliminate_empty_blocks(graph): From pedronis at codespeak.net Sat Oct 1 05:16:56 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 05:16:56 +0200 (CEST) Subject: [pypy-svn] r18040 - in pypy/dist/pypy/translator: goal tool tool/pygame Message-ID: <20051001031656.3CB8227BDF@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 05:16:52 2005 New Revision: 18040 Removed: pypy/dist/pypy/translator/tool/pygame/server.py Modified: pypy/dist/pypy/translator/goal/driver.py pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/goal/translate_pypy_new.py pypy/dist/pypy/translator/tool/graphserver.py pypy/dist/pypy/translator/tool/pdbplus.py pypy/dist/pypy/translator/tool/util.py Log: mostly done. - implemented forking - llvm goals (they need testing) - logging ... TODO: - llinterpret - pdbplus: graphserver - util? - states/ polish? Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Sat Oct 1 05:16:52 2005 @@ -8,23 +8,30 @@ from pypy.annotation import policy as annpolicy import optparse +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("translation") +py.log.setconsumer("translation", ansi_log) + + DEFAULT_OPTIONS = optparse.Values(defaults={ 'gc': 'ref', 'debug': True, 'insist': False, 'backend': 'c', 'lowmem': False, + 'fork_before': None }) -def taskdef(taskfunc, deps, title, new_state=None, expected_states=[]): +def taskdef(taskfunc, deps, title, new_state=None, expected_states=[], idemp=False): taskfunc.task_deps = deps taskfunc.task_title = title taskfunc.task_newstate = None taskfunc.task_expected_states = expected_states + taskfunc.task_idempotent = idemp return taskfunc # TODO: -# run is idempotent # sanity-checks using states class TranslationDriver(SimpleTaskEngine): @@ -92,7 +99,7 @@ return l def info(self, msg): - print msg + log.info(msg) def _do(self, goal, func, *args, **kwds): title = func.task_title @@ -102,7 +109,8 @@ else: self.info("%s..." % title) func() - self.done[goal] = True + if not func.task_idempotent: + self.done[goal] = True def task_annotate(self): @@ -113,11 +121,33 @@ annmodel.DEBUG = self.options.debug annotator = translator.annotate(self.inputtypes, policy=policy) - sanity_check_annotation(translator) + self.sanity_check_annotation() annotator.simplify() # task_annotate = taskdef(task_annotate, [], "Annotating&simplifying") + + def sanity_check_annotation(self): + translator = self.translator + irreg = query.qoutput(query.check_exceptblocks_qgen(translator)) + if not irreg: + self.info("All exceptblocks seem sane") + + lost = query.qoutput(query.check_methods_qgen(translator)) + assert not lost, "lost methods, something gone wrong with the annotation of method defs" + self.info("No lost method defs") + + so = query.qoutput(query.polluted_qgen(translator)) + tot = len(translator.flowgraphs) + percent = int(tot and (100.0*so / tot) or 0) + if percent == 0: + pr = self.info + else: + pr = log.WARNING + pr("-- someobjectness %2d%% (%d of %d functions polluted by SomeObjects)" % (percent, so, tot)) + + + def task_rtype(self): opt = self.options self.translator.specialize(dont_simplify_again=True, @@ -160,7 +190,12 @@ cbuilder.compile() if self.standalone: - self.c_entryp = cbuilder.executable_name + c_entryp = cbuilder.executable_name + import shutil + exename = mkexename(c_entryp) + newexename = mkexename('./'+'pypy-c') + shutil.copy(exename, newexename) + self.c_entryp = newexename self.info("written: %s" % (self.c_entryp,)) else: cbuilder.import_module() @@ -168,15 +203,9 @@ # task_compile_c = taskdef(task_compile_c, ['source_c'], "Compiling c source") - def backend_run(self, backend): # xxx mess + def backend_run(self, backend): c_entryp = self.c_entryp standalone = self.standalone - if standalone: # xxx fragile and messy - import shutil - exename = mkexename(c_entryp) - newexename = mkexename('./pypy-' + backend) - shutil.copy(exename, newexename) - c_entryp = newexename if standalone: os.system(c_entryp) else: @@ -185,24 +214,44 @@ def task_run_c(self): self.backend_run('c') # - task_run_c = taskdef(task_run_c, ['compile_c'], "Running compiled c source") - - def task_llinterpret(self): - raise NotImplementedError, "llinterpret" # xxx + task_run_c = taskdef(task_run_c, ['compile_c'], + "Running compiled c source", + idemp=True) + + def task_llinterpret(self): # TODO + #def interpret(): + # from pypy.rpython.llinterp import LLInterpreter + # py.log.setconsumer("llinterp operation", None) + # interp = LLInterpreter(translator.flowgraphs, transalator.rtyper) + # interp.eval_function(translator.entrypoint, + # targetspec_dic['get_llinterp_args']()) + #interpret() + raise NotImplementedError # task_llinterpret = taskdef(task_llinterpret, ['?backendopt', 'rtype'], "LLInterpeting") - def task_source_llvm(self): - raise NotImplementedError, "source_llvm" # xxx + def task_source_llvm(self): # xxx messy + translator = self.translator + opts = self.options + if translator.annotator is None: + raise ValueError, "function has to be annotated." + from pypy.translator.llvm import genllvm + self.llvmgen = genllvm.GenLLVM(translator, + genllvm.GcPolicy.new(opts.gc), + genllvm.ExceptionPolicy.new(None)) + self.llvm_filename = gen.gen_llvm_source() + self.info("written: %s" % (self.llvm_filename,)) # task_source_llvm = taskdef(task_source_llvm, ['backendopt', 'rtype'], "Generating llvm source") - def task_compile_llvm(self): - raise NotImplementedError, "compile_llvm" # xxx + def task_compile_llvm(self): # xxx messy + self.c_entryp = self.llvmgen.compile_module(self.llvm_filename, + standalone=self.standalone, + exe_name = 'pypy-llvm') # task_compile_llvm = taskdef(task_compile_llvm, ['backendopt', 'rtype'], @@ -212,7 +261,8 @@ self.backend_run('llvm') # task_run_llvm = taskdef(task_run_llvm, ['compile_llvm'], - "Running compiled llvm source") + "Running compiled llvm source", + idemp=True) def proceed(self, goals): if not goals: @@ -234,8 +284,12 @@ if options is None: options = DEFAULT_OPTIONS.copy() - target = targetspec_dic['target'] - spec = target(options, args) + target = targetspec_dic['target'] + try: + options.log = log + spec = target(options, args) + finally: + del options.log try: entry_point, inputtypes, policy = spec except ValueError: @@ -258,21 +312,21 @@ from_targetspec = staticmethod(from_targetspec) + def prereq_checkpt_rtype(self): + assert_rtyper_not_imported() -# __________ helpers + # checkpointing support + def _event(self, kind, goal, func): + if kind == 'pre': + fork_before = self.options.fork_before + if fork_before: + fork_before, = self.backend_select_goals([fork_before]) + if not fork_before in self.done and fork_before == goal: + prereq = getattr(self, 'prereq_checkpt_%s' % goal, None) + if prereq: + prereq() + from pypy.translator.goal import unixcheckpoint + unixcheckpoint.restartable_point(auto='run') -def sanity_check_annotation(t): - irreg = query.qoutput(query.check_exceptblocks_qgen(t)) - if not irreg: - print "++ All exceptblocks seem sane" - - lost = query.qoutput(query.check_methods_qgen(t)) - assert not lost, "lost methods, something gone wrong with the annotation of method defs" - print "++ No lost method defs" - - so = query.qoutput(query.polluted_qgen(t)) - tot = len(t.flowgraphs) - percent = int(tot and (100.0*so / tot) or 0) - print "-- someobjectness %2d%% (%d of %d functions polluted by SomeObjects)" % (percent, so, tot) -from pypy.translator.tool.util import mkexename +from pypy.translator.tool.util import mkexename, assert_rtyper_not_imported 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 Sat Oct 1 05:16:52 2005 @@ -302,8 +302,10 @@ global serv_start, serv_show, serv_stop, serv_cleanup from pypy.translator.tool import graphpage, graphserver homepage = graphpage.TranslatorPage(t) - (serv_start, serv_show, serv_stop, serv_cleanup + (serv_start, serv_show, serv_stop )=graphserver.run_server(homepage, port=listen_port, background=True) + def serv_cleanup(): + pass def run_server(): Modified: pypy/dist/pypy/translator/goal/translate_pypy_new.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy_new.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy_new.py Sat Oct 1 05:16:52 2005 @@ -73,8 +73,12 @@ '4_graphserve': [OPT(('--graphserve',), """Serve analysis graphs on port number (see pypy/translator/tool/pygame/graphclient.py)""", int)], + '5_fork_before': [OPT(('--fork-before',), """(UNIX) Create restartable checkpoint before step""", + ['annotate', 'rtype', 'backendopt', 'source'])], + }, + #'Process options':[ # ['-f', '--fork', @@ -103,12 +107,16 @@ 'text': False, 'graphserve': None, 'huge': 100, + + 'fork_before': None } import py # we want 2.4 expand_default functionality optparse = py.compat.optparse - +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("translation") +py.log.setconsumer("translation", ansi_log) class OptHelpFormatter(optparse.IndentedHelpFormatter): @@ -141,11 +149,11 @@ parser.values.skipped_goals = parser.values.skipped_goals + [goal] def load_target(targetspec): + log.info("Translating target as defined by %s" % targetspec) if not targetspec.endswith('.py'): targetspec += '.py' targetspec_dic = {} sys.path.insert(0, os.path.dirname(targetspec)) - #xxx print execfile(targetspec, targetspec_dic) return targetspec_dic @@ -193,6 +201,10 @@ options.targetspec = arg[:-3] targespec_dic = load_target(options.targetspec) + + # tweak: default_goals into default_goal + del options.default_goals + options.default_goal = 'compile' return targespec_dic, options, args @@ -202,18 +214,18 @@ from pypy.translator import translator from pypy.translator.goal import driver from pypy.translator.tool.pdbplus import PdbPlusShow - from pypy.translator.tool.graphserver import run_async_server - + t = translator.Translator() if options.graphserve: - serv_start, serv_show, serv_stop, serv_cleanup = run_async_server(t, options.graphserve) + from pypy.translator.tool.graphserver import run_async_server + serv_start, serv_show, serv_stop = run_async_server(t, options) def server_setup(): - return serv_start, serv_show, serv_stop, serv_cleanup + return serv_start, serv_show, serv_stop else: def server_setup(): - from pypy.translator.tool.pygame.server import run_translator_server - return run_translator_server(t, options) + from pypy.translator.tool.graphserver import run_server_for_inprocess_client + return run_server_for_inprocess_client(t, options) pdb_plus_show = PdbPlusShow(t) # need a translator to support extended commands @@ -221,28 +233,36 @@ tb = None if got_error: import traceback + errmsg = ["Error:\n"] exc, val, tb = sys.exc_info() - print >> sys.stderr - traceback.print_exception(exc, val, tb) - print >> sys.stderr - + errmsg.extend([" %s" % line for line in traceback.format_exception(exc, val, tb)]) block = getattr(val, '__annotator_block', None) if block: - print '-'*60 - t.about(block) - print '-'*60 - print + class FileLike: + def write(self, s): + errmsg.append(" %s" % s) + errmsg.append("Processing block:\n") + t.about(block, FileLike()) + log.ERROR(''.join(errmsg)) else: - print '-'*60 - print 'Done.' - print + log.event('Done.') if options.batch: - print >>sys.stderr, "batch mode, not calling interactive helpers" + log.event("batch mode, not calling interactive helpers") return + + log.event("start debugger...") pdb_plus_show.start(tb, server_setup, graphic=not options.text) + # list options (xxx filter, filter for target) + log('options in effect:') + optnames = options.__dict__.keys() + optnames.sort() + for name in optnames: + optvalue = getattr(options, name) + log('%25s: %s' %(name, optvalue)) + try: drv = driver.TranslationDriver.from_targetspec(targetspec_dic, options, args, empty_translator=t, Modified: pypy/dist/pypy/translator/tool/graphserver.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphserver.py (original) +++ pypy/dist/pypy/translator/tool/graphserver.py Sat Oct 1 05:16:52 2005 @@ -10,11 +10,10 @@ send_msg = portutil.send_msg recv_msg = portutil.recv_msg -def run_async_server(t, listen_port): +def run_async_server(t, options): import graphpage - homepage = graphpage.TranslatorPage(t) - print repr(t),repr(homepage) - return run_server(homepage, port=listen_port, background=True) + homepage = graphpage.TranslatorPage(t, options.huge) + return run_server(homepage, port=options.graphserve, background=True) class GraphserverPort(portutil.Port): @@ -76,7 +75,7 @@ portutil.run_server(make_port, port=port, quiet=quiet, background=background) - return start, show, stop, stop + return start, show, stop class MissingPage: links = {} @@ -87,3 +86,18 @@ ''' def content(self): return self + +# + +def run_server_for_inprocess_client(t, options): + from pypy.translator.tool import graphpage + from pypy.translator.tool.pygame.graphclient import get_layout + from pypy.translator.tool.pygame.graphdisplay import GraphDisplay + + page = graphpage.TranslatorPage(t, options.huge) + + layout = get_layout(page) + show, async_quit = layout.connexion.initiate_display, layout.connexion.quit + display = layout.get_display() + return display.run, show, async_quit + Modified: pypy/dist/pypy/translator/tool/pdbplus.py ============================================================================== --- pypy/dist/pypy/translator/tool/pdbplus.py (original) +++ pypy/dist/pypy/translator/tool/pdbplus.py Sat Oct 1 05:16:52 2005 @@ -388,10 +388,9 @@ pass else: return - start, show, stop, cleanup = server_setup() + start, show, stop = server_setup() self.install_show(show) debugger = self._run_debugger_in_thread(tb, stop) debugger.start() start() debugger.join() - cleanup() Modified: pypy/dist/pypy/translator/tool/util.py ============================================================================== --- pypy/dist/pypy/translator/tool/util.py (original) +++ pypy/dist/pypy/translator/tool/util.py Sat Oct 1 05:16:52 2005 @@ -23,7 +23,7 @@ name = os.path.normpath(name + '.exe') return name -def assert_rpython_mostly_not_imported(): +def assert_rtyper_not_imported(): prefix = 'pypy.rpython.' oknames = ('rarithmetic memory memory.lladdress extfunctable ' 'lltype objectmodel error ros'.split()) From pedronis at codespeak.net Sat Oct 1 05:31:24 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 05:31:24 +0200 (CEST) Subject: [pypy-svn] r18041 - pypy/dist/pypy/translator/goal Message-ID: <20051001033124.BC92027BDC@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 05:31:23 2005 New Revision: 18041 Modified: pypy/dist/pypy/translator/goal/driver.py Log: oops, confusing between source/compile info message Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Sat Oct 1 05:31:23 2005 @@ -179,6 +179,7 @@ cbuilder = translator.cbuilder(standalone=standalone, gcpolicy=gcpolicy) c_source_filename = cbuilder.generate_source() + self.info("written: %s" % (c_source_filename,)) self.cbuilder = cbuilder # task_source_c = taskdef(task_source_c, @@ -196,7 +197,7 @@ newexename = mkexename('./'+'pypy-c') shutil.copy(exename, newexename) self.c_entryp = newexename - self.info("written: %s" % (self.c_entryp,)) + self.info("created: %s" % (self.c_entryp,)) else: cbuilder.import_module() self.c_entryp = cbuilder.get_entry_point() From pedronis at codespeak.net Sat Oct 1 05:51:23 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 05:51:23 +0200 (CEST) Subject: [pypy-svn] r18042 - pypy/dist/pypy/translator/goal Message-ID: <20051001035123.EA68F27BE1@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 05:51:22 2005 New Revision: 18042 Modified: pypy/dist/pypy/translator/goal/driver.py pypy/dist/pypy/translator/goal/translate_pypy_new.py Log: implemented llinterpret Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Sat Oct 1 05:51:22 2005 @@ -37,7 +37,7 @@ class TranslationDriver(SimpleTaskEngine): def __init__(self, translator, inputtypes, policy=None, options=None, - runner=None, disable=[], default_goal = None): + runner=None, disable=[], default_goal = None, extra = {}): SimpleTaskEngine.__init__(self) self.translator = translator @@ -61,6 +61,8 @@ f() self.runner = runner + self.extra = extra + self.done = {} maybe_skip = [] @@ -82,7 +84,7 @@ self.proceed(backend_goal) setattr(self, task, proc) - for task in ('annotate', 'rtype', 'backendopt', 'source', 'compile', 'run'): + for task in ('annotate', 'rtype', 'backendopt', 'source', 'compile', 'run', 'llinterpret'): expose_task(task) def backend_select_goals(self, goals): @@ -219,15 +221,17 @@ "Running compiled c source", idemp=True) - def task_llinterpret(self): # TODO - #def interpret(): - # from pypy.rpython.llinterp import LLInterpreter - # py.log.setconsumer("llinterp operation", None) - # interp = LLInterpreter(translator.flowgraphs, transalator.rtyper) - # interp.eval_function(translator.entrypoint, - # targetspec_dic['get_llinterp_args']()) - #interpret() - raise NotImplementedError + def task_llinterpret(self): + from pypy.rpython.llinterp import LLInterpreter + py.log.setconsumer("llinterp operation", None) + + translator = self.translator + interp = LLInterpreter(translator.flowgraphs, translator.rtyper) + v = interp.eval_function(translator.entrypoint, + self.extra.get('get_llinterp_args', + lambda: [])()) + + log.llinterpret.event("result -> %s" % v) # task_llinterpret = taskdef(task_llinterpret, ['?backendopt', 'rtype'], @@ -307,7 +311,8 @@ driver = TranslationDriver(translator, inputtypes, policy, options, targetspec_dic.get('run'), disable=disable, - default_goal = default_goal) + default_goal = default_goal, + extra = targetspec_dic) return driver Modified: pypy/dist/pypy/translator/goal/translate_pypy_new.py ============================================================================== --- pypy/dist/pypy/translator/goal/translate_pypy_new.py (original) +++ pypy/dist/pypy/translator/goal/translate_pypy_new.py Sat Oct 1 05:51:22 2005 @@ -76,14 +76,9 @@ '5_fork_before': [OPT(('--fork-before',), """(UNIX) Create restartable checkpoint before step""", ['annotate', 'rtype', 'backendopt', 'source'])], + '6_llinterpret': [OPT(('--llinterpret',), "Interpret the rtyped flow graphs", GOAL)], }, - - - #'Process options':[ - # ['-f', '--fork', - # "(UNIX) Create restartable checkpoint after annotation [,specialization]", - # [['fork1','fork2']], [] ], } From pedronis at codespeak.net Sat Oct 1 06:14:34 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 06:14:34 +0200 (CEST) Subject: [pypy-svn] r18043 - pypy/dist/pypy/translator/goal Message-ID: <20051001041434.1610327BE2@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 06:14:32 2005 New Revision: 18043 Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: filter out log Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Sat Oct 1 06:14:32 2005 @@ -53,6 +53,8 @@ import pypy.module.sys d = {} for key, value in options.__dict__.items(): + if key == 'log': + continue d[key.lstrip('-')] = value wrapstr = 'space.wrap(%r)' % (d,) pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] = wrapstr From arigo at codespeak.net Sat Oct 1 11:43:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 11:43:02 +0200 (CEST) Subject: [pypy-svn] r18044 - in pypy/dist/pypy/translator/tool: . pygame Message-ID: <20051001094302.A59C527BE4@code1.codespeak.net> Author: arigo Date: Sat Oct 1 11:42:56 2005 New Revision: 18044 Modified: pypy/dist/pypy/translator/tool/port.py pypy/dist/pypy/translator/tool/pygame/graphclient.py Log: Try to use the local 'dot' before codespeak's. I'm not 100% sure it will catch all cases, but I think that most ways in which the buggy 'dot' can fail will leave behind a file that GraphLayout.__init__() will fail to parse. An idea for py.execnet too: passing marshal data over a socket can be fine if the receiver is ready to use pypy/lib/_marshal.py to decode it (2.3/2.4 conflict). --This line, and those below, will be ignored-- M tool/pygame/graphclient.py M tool/port.py Modified: pypy/dist/pypy/translator/tool/port.py ============================================================================== --- pypy/dist/pypy/translator/tool/port.py (original) +++ pypy/dist/pypy/translator/tool/port.py Sat Oct 1 11:42:56 2005 @@ -17,7 +17,12 @@ 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) + try: + return marshal.loads(msg) + except ValueError: + # fall-back if Python 2.3 receives a 2.4 marshal format + from pypy.lib._marshal import loads + return loads(msg) def send_msg(s, msg): data = marshal.dumps(msg) 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 Sat Oct 1 11:42:56 2005 @@ -8,16 +8,15 @@ 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 +import py DOT_FILE = udir.join('graph.dot') PLAIN_FILE = udir.join('graph.plain') -import py -def dot2plain(dotfile, plainfile): - if 0: - cmdexec('dot -Tplain %s>%s' % (dotfile, plainfile)) +def dot2plain(dotfile, plainfile, use_codespeak=False): + if not use_codespeak: + py.process.cmdexec('dot -Tplain %s>%s' % (dotfile, plainfile)) elif 0: gw = py.execnet.SshGateway('codespeak.net') channel = gw.remote_exec(""" @@ -36,27 +35,22 @@ import urllib content = py.path.local(dotfile).read() request = urllib.urlencode({'dot': content}) - try: - urllib.urlretrieve('http://codespeak.net/pypy/convertdot.cgi', - str(plainfile), - data=request) - except IOError: - success = False - else: - plainfile = py.path.local(plainfile) - success = (plainfile.check(file=1) and - plainfile.read().startswith('graph ')) - if not success: - print "NOTE: failed to use codespeak's convertdot.cgi, trying local 'dot'" - cmdexec('dot -Tplain %s>%s' % (dotfile, plainfile)) + urllib.urlretrieve('http://codespeak.net/pypy/convertdot.cgi', + str(plainfile), + data=request) class ClientGraphLayout(GraphLayout): def __init__(self, connexion, key, dot, links, **ignored): # generate a temporary .dot file and call dot on it DOT_FILE.write(dot) - dot2plain(DOT_FILE, PLAIN_FILE) - GraphLayout.__init__(self, PLAIN_FILE) + try: + dot2plain(DOT_FILE, PLAIN_FILE, use_codespeak=False) + GraphLayout.__init__(self, PLAIN_FILE) + except (py.error.Error, IOError, TypeError, ValueError): + # failed, try via codespeak + dot2plain(DOT_FILE, PLAIN_FILE, use_codespeak=True) + GraphLayout.__init__(self, PLAIN_FILE) self.connexion = connexion self.key = key self.links.update(links) From arigo at codespeak.net Sat Oct 1 12:22:06 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 12:22:06 +0200 (CEST) Subject: [pypy-svn] r18045 - pypy/dist/pypy/translator/tool/pygame Message-ID: <20051001102206.8CC6227BE7@code1.codespeak.net> Author: arigo Date: Sat Oct 1 12:22:00 2005 New Revision: 18045 Modified: 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: A bit of reorganization: on remote connexions, the status bar "loading..." text immediately disappeared while waiting for the page to arrive, which gave the user the impression that clicking on a link didn't go anywhere. 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 Sat Oct 1 12:22:00 2005 @@ -93,6 +93,21 @@ def display_async_cmd(**kwds): pygame.event.post(pygame.event.Event(USEREVENT, **kwds)) +EventQueue = [] + +def wait_for_events(): + if not EventQueue: + EventQueue.append(pygame.event.wait()) + EventQueue.extend(pygame.event.get()) + +def wait_for_async_cmd(): + # wait until another thread pushes a USEREVENT in the queue + while True: + wait_for_events() + e = EventQueue.pop(0) + if e.type in (USEREVENT, QUIT): # discard all other events + break + EventQueue.insert(0, e) # re-insert the event for further processing class Node: 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 Sat Oct 1 12:22:00 2005 @@ -5,7 +5,9 @@ import autopath from pypy.translator.tool.pygame.drawgraph import GraphLayout -from pypy.translator.tool.pygame.drawgraph import display_async_cmd, display_async_quit +from pypy.translator.tool.pygame.drawgraph import display_async_cmd +from pypy.translator.tool.pygame.drawgraph import display_async_quit +from pypy.translator.tool.pygame.drawgraph import wait_for_async_cmd from pypy.translator.tool.graphserver import MissingPage, portutil from pypy.tool.udir import udir import py @@ -89,6 +91,7 @@ def initiate_display(self, key, link=None): self.put_msg((key, link)) + wait_for_async_cmd() def on_msg(self, msg): if msg is None: 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 Sat Oct 1 12:22:00 2005 @@ -5,6 +5,7 @@ from pygame.locals import * from pypy.translator.tool.pygame.drawgraph import GraphRenderer from pypy.translator.tool.pygame.drawgraph import Node, Edge +from pypy.translator.tool.pygame.drawgraph import EventQueue, wait_for_events METAKEYS = dict([ @@ -230,9 +231,12 @@ pygame.display.flip() while True: - e = pygame.event.wait() + wait_for_events() + e = EventQueue.pop(0) if e.type in (MOUSEBUTTONDOWN, KEYDOWN, QUIT): break + if e.type == QUIT: + EventQueue.insert(0, e) # re-insert a QUIT self.must_redraw = True def input(self, prompt): @@ -271,11 +275,13 @@ text = "" self.must_redraw = True while True: - events = [pygame.event.wait()] - events.extend(pygame.event.get()) + wait_for_events() old_text = text + events = EventQueue[:] + del EventQueue[:] for e in events: if e.type == QUIT: + EventQueue.insert(0, e) # re-insert a QUIT return None elif e.type == KEYDOWN: if e.key == K_ESCAPE: @@ -565,7 +571,7 @@ return moving def peek(self, typ): - for event in self.events: + for event in EventQueue: if event.type == typ: return True return False @@ -652,19 +658,17 @@ def run(self): self.dragging = self.click_origin = self.click_time = None - events = self.events = [] try: while True: - if self.must_redraw and not events: + if self.must_redraw and not EventQueue: self.redraw_now() - if not events: - events.append(pygame.event.wait()) - events.extend(pygame.event.get()) + if not EventQueue: + wait_for_events() - self.process_event(events.pop(0)) + self.process_event(EventQueue.pop(0)) except StopIteration: pass From arigo at codespeak.net Sat Oct 1 13:39:19 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 13:39:19 +0200 (CEST) Subject: [pypy-svn] r18046 - pypy/dist/pypy/translator/c Message-ID: <20051001113919.39B2027BEC@code1.codespeak.net> Author: arigo Date: Sat Oct 1 13:39:16 2005 New Revision: 18046 Modified: pypy/dist/pypy/translator/c/funcgen.py Log: Fix the logic for the return variable, for the case where the function only raises exceptions but the return variable is still not "void" (because of call normalization). Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Sat Oct 1 13:39:16 2005 @@ -35,41 +35,40 @@ # # NOTE: cannot use dictionaries with Constants as keys, because # Constants may hash and compare equal but have different lltypes - mix = [] + mix = [self.graph.getreturnvar()] self.more_ll_values = [] - def visit(block): - if isinstance(block, Block): - mix.extend(block.inputargs) - for op in block.operations: - mix.extend(op.args) - mix.append(op.result) - for link in block.exits: - mix.extend(link.getextravars()) - mix.extend(link.args) - if hasattr(link, 'llexitcase'): - self.more_ll_values.append(link.llexitcase) - elif link.exitcase is not None: - mix.append(Constant(link.exitcase)) - traverse(visit, graph) - resultvar = graph.getreturnvar() + for block in graph.iterblocks(): + mix.extend(block.inputargs) + for op in block.operations: + mix.extend(op.args) + mix.append(op.result) + for link in block.exits: + mix.extend(link.getextravars()) + mix.extend(link.args) + if hasattr(link, 'llexitcase'): + self.more_ll_values.append(link.llexitcase) + elif link.exitcase is not None: + mix.append(Constant(link.exitcase)) - self.vars = mix - self.lltypes = None - for v in self.vars: + uniquemix = [] + seen = {} + for v in mix: + if id(v) not in seen: + uniquemix.append(v) + seen[id(v)] = True T = getattr(v, 'concretetype', PyObjPtr) - db.gettype(T) + db.gettype(T) # force the type to be considered by the database + self.vars = uniquemix + self.lltypes = None def implementation_begin(self): db = self.db - resultvar = self.graph.getreturnvar() - self.lltypes = { - # default, normally overridden: - id(resultvar): (Void, db.gettype(Void)), - } + lltypes = {} for v in self.vars: T = getattr(v, 'concretetype', PyObjPtr) typename = db.gettype(T) - self.lltypes[id(v)] = T, typename + lltypes[id(v)] = T, typename + self.lltypes = lltypes def implementation_end(self): self.lltypes = None From arigo at codespeak.net Sat Oct 1 14:16:09 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 14:16:09 +0200 (CEST) Subject: [pypy-svn] r18047 - pypy/dist/pypy/translator/llvm/backendopt Message-ID: <20051001121609.C90C327BEE@code1.codespeak.net> Author: arigo Date: Sat Oct 1 14:15:53 2005 New Revision: 18047 Modified: pypy/dist/pypy/translator/llvm/backendopt/ (props changed) pypy/dist/pypy/translator/llvm/backendopt/__init__.py (props changed) pypy/dist/pypy/translator/llvm/backendopt/exception.py (props changed) pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py (props changed) pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py (props changed) Log: fixeol From arigo at codespeak.net Sat Oct 1 14:16:16 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 14:16:16 +0200 (CEST) Subject: [pypy-svn] r18048 - pypy/dist/pypy/translator/tool Message-ID: <20051001121616.11E8127BF4@code1.codespeak.net> Author: arigo Date: Sat Oct 1 14:16:13 2005 New Revision: 18048 Modified: pypy/dist/pypy/translator/tool/graphpage.py Log: Trying to make graphpage semi-safe against data structures being modified under its feet by translate_pypy in the main thread. Modified: pypy/dist/pypy/translator/tool/graphpage.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphpage.py (original) +++ pypy/dist/pypy/translator/tool/graphpage.py Sat Oct 1 14:16:13 2005 @@ -112,8 +112,7 @@ self.current_value = {} self.caused_by = {} if self.annotator: - for var in self.annotator.bindings: - s_value = self.annotator.binding(var) + for var, s_value in self.annotator.bindings.items(): info = '%s: %s' % (var.name, s_value) self.links[var.name] = info self.current_value[var.name] = s_value @@ -210,7 +209,7 @@ self.source = dotgen.generate(target=None) # link the function names to the individual flow graphs - for name, obj in self.object_by_name.iteritems(): + for name, obj in self.object_by_name.items(): if isinstance(obj, ClassDef): #data = '%s.%s' % (obj.cls.__module__, obj.cls.__name__) data = repr(obj.cls) @@ -284,7 +283,8 @@ translator = self.translator # show the call graph - functions = translator.functions + callgraph = translator.callgraph.values() + functions = list(translator.functions) if len(functions) > huge: LocalizedCallGraphPage.do_compute.im_func(self, dotgen, translator.entrypoint) @@ -310,7 +310,7 @@ dotgen.emit_node(nameof(func), label=data, shape="box", **kw) if functions: dotgen.emit_edge('entry', nameof(functions[0]), color="green") - for f1, f2 in translator.callgraph.itervalues(): + for f1, f2 in callgraph: # captured above (multithreading fun) dotgen.emit_edge(nameof(f1), nameof(f2)) # show the class hierarchy @@ -329,7 +329,7 @@ functions = {} - for f1, f2 in translator.callgraph.itervalues(): + for f1, f2 in translator.callgraph.values(): if f1 is func0 or f2 is func0: dotgen.emit_edge(nameof(f1), nameof(f2)) functions[f1] = True From pedronis at codespeak.net Sat Oct 1 14:40:32 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 14:40:32 +0200 (CEST) Subject: [pypy-svn] r18049 - pypy/dist/pypy/translator/goal Message-ID: <20051001124032.0F7E027BF3@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 14:40:30 2005 New Revision: 18049 Modified: pypy/dist/pypy/translator/goal/driver.py Log: - fixes to llvm goals - removed runner argument to driver constructor, take it from extra dict Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Sat Oct 1 14:40:30 2005 @@ -37,7 +37,7 @@ class TranslationDriver(SimpleTaskEngine): def __init__(self, translator, inputtypes, policy=None, options=None, - runner=None, disable=[], default_goal = None, extra = {}): + disable=[], default_goal = None, extra = {}): SimpleTaskEngine.__init__(self) self.translator = translator @@ -56,11 +56,6 @@ self.options = options self.standalone = standalone - if runner is None and not standalone: - def runner(f): - f() - self.runner = runner - self.extra = extra self.done = {} @@ -212,7 +207,8 @@ if standalone: os.system(c_entryp) else: - self.runner(c_entryp) + runner = self.extra.get('run', lambda f: f()) + runner(c_entryp) def task_run_c(self): self.backend_run('c') @@ -246,7 +242,7 @@ self.llvmgen = genllvm.GenLLVM(translator, genllvm.GcPolicy.new(opts.gc), genllvm.ExceptionPolicy.new(None)) - self.llvm_filename = gen.gen_llvm_source() + self.llvm_filename = self.llvmgen.gen_llvm_source() self.info("written: %s" % (self.llvm_filename,)) # task_source_llvm = taskdef(task_source_llvm, @@ -254,12 +250,12 @@ "Generating llvm source") def task_compile_llvm(self): # xxx messy - self.c_entryp = self.llvmgen.compile_module(self.llvm_filename, - standalone=self.standalone, - exe_name = 'pypy-llvm') + self.c_entryp = self.llvmgen.create_module(self.llvm_filename, + standalone=self.standalone, + exe_name = 'pypy-llvm') # task_compile_llvm = taskdef(task_compile_llvm, - ['backendopt', 'rtype'], + ['source_llvm'], "Compiling llvm source") def task_run_llvm(self): @@ -309,7 +305,7 @@ translator = Translator(entry_point, verbose=True, simplifying=True) driver = TranslationDriver(translator, inputtypes, - policy, options, targetspec_dic.get('run'), + policy, options, disable=disable, default_goal = default_goal, extra = targetspec_dic) From arigo at codespeak.net Sat Oct 1 14:50:50 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 14:50:50 +0200 (CEST) Subject: [pypy-svn] r18050 - pypy/dist/pypy/translator/goal Message-ID: <20051001125050.9542827BF5@code1.codespeak.net> Author: arigo Date: Sat Oct 1 14:50:49 2005 New Revision: 18050 Modified: pypy/dist/pypy/translator/goal/richards.py pypy/dist/pypy/translator/goal/targetrichards.py Log: Give richards.py command-line and functional arguments to select the number of iterations. Modified: pypy/dist/pypy/translator/goal/richards.py ============================================================================== --- pypy/dist/pypy/translator/goal/richards.py (original) +++ pypy/dist/pypy/translator/goal/richards.py Sat Oct 1 14:50:49 2005 @@ -361,10 +361,8 @@ class Richards(object): - iterations = 10 - - def run(self): - for i in xrange(self.iterations): + def run(self, iterations): + for i in xrange(iterations): taskWorkArea.holdCount = 0 taskWorkArea.qpktCount = 0 @@ -397,23 +395,27 @@ return True -def entry_point(): +def entry_point(iterations): r = Richards() startTime = time.time() - result = r.run() + result = r.run(iterations) endTime = time.time() return result, startTime, endTime -def main(entry_point = entry_point): +def main(entry_point = entry_point, iterations = 10): print "Richards benchmark (Python) starting... [%r]" % entry_point - result, startTime, endTime = entry_point() + result, startTime, endTime = entry_point(iterations) if not result: print "Incorrect results!" return print "finished." total_s = endTime - startTime - print "Total time for %d iterations: %d secs" %(Richards.iterations,total_s) - print "Average time for iterations: %d ms" %(total_s*1000/Richards.iterations) + print "Total time for %d iterations: %.2f secs" %(iterations,total_s) + print "Average time per iteration: %.2f ms" %(total_s*1000/iterations) if __name__ == '__main__': - main() + import sys + if len(sys.argv) >= 2: + main(iterations = int(sys.argv[1])) + else: + main() Modified: pypy/dist/pypy/translator/goal/targetrichards.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrichards.py (original) +++ pypy/dist/pypy/translator/goal/targetrichards.py Sat Oct 1 14:50:49 2005 @@ -5,7 +5,7 @@ # _____ Define and setup target ___ def target(*args): - return entry_point, [] + return entry_point, [int] def get_llinterp_args(): return [] @@ -13,8 +13,8 @@ # _____ Run translated _____ def run(c_entry_point): print "Translated:" - richards.main(c_entry_point) + richards.main(c_entry_point, iterations=500) print "CPython:" - richards.main() + richards.main(iterations=5) From pedronis at codespeak.net Sat Oct 1 14:56:01 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 14:56:01 +0200 (CEST) Subject: [pypy-svn] r18051 - pypy/dist/pypy/translator/goal Message-ID: <20051001125601.218E827BFD@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 14:55:57 2005 New Revision: 18051 Removed: pypy/dist/pypy/translator/goal/translate_pypy.py Log: this one is going away... From pedronis at codespeak.net Sat Oct 1 14:56:46 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 14:56:46 +0200 (CEST) Subject: [pypy-svn] r18052 - pypy/dist/pypy/translator/goal Message-ID: <20051001125646.DEDE427C04@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 14:56:44 2005 New Revision: 18052 Added: pypy/dist/pypy/translator/goal/translate_pypy.py - copied unchanged from r18050, pypy/dist/pypy/translator/goal/translate_pypy_new.py Removed: pypy/dist/pypy/translator/goal/translate_pypy_new.py Log: translate_pypy_new becomes the translate_pypy From pedronis at codespeak.net Sat Oct 1 15:44:53 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 15:44:53 +0200 (CEST) Subject: [pypy-svn] r18053 - pypy/dist/pypy/translator/goal Message-ID: <20051001134453.E4FFA27C08@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 15:44:51 2005 New Revision: 18053 Modified: pypy/dist/pypy/translator/goal/driver.py pypy/dist/pypy/translator/goal/targetcompiler.py pypy/dist/pypy/translator/goal/targetpypymain.py pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: pass a driver instead of just options to the target() defining functions, driver has options and a log attached Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Sat Oct 1 15:44:51 2005 @@ -36,28 +36,15 @@ class TranslationDriver(SimpleTaskEngine): - def __init__(self, translator, inputtypes, policy=None, options=None, - disable=[], default_goal = None, extra = {}): + def __init__(self, options=None, default_goal=None, disable=[]): SimpleTaskEngine.__init__(self) - self.translator = translator - - standalone = inputtypes is None - if standalone: - ldef = listdef.ListDef(None, annmodel.SomeString()) - inputtypes = [annmodel.SomeList(ldef)] - self.inputtypes = inputtypes + self.log = log - if policy is None: - policy = annpolicy.AnnotatorPolicy() - self.policy = policy if options is None: - options = DEFAULT_OPTIONS + options = DEFAULT_OPTIONS self.options = options - self.standalone = standalone - - self.extra = extra - + self.done = {} maybe_skip = [] @@ -95,16 +82,41 @@ l.append(goal) return l + def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None): + standalone = inputtypes is None + self.standalone = standalone + + if standalone: + ldef = listdef.ListDef(None, annmodel.SomeString()) + inputtypes = [annmodel.SomeList(ldef)] + self.inputtypes = inputtypes + + if policy is None: + policy = annpolicy.AnnotatorPolicy() + self.policy = policy + + self.extra = extra + + if empty_translator: + # re-initialize it + empty_translator.__init__(entry_point, verbose=True, simplifying=True) + translator = empty_translator + else: + translator = Translator(entry_point, verbose=True, simplifying=True) + + self.translator = translator + + def info(self, msg): log.info(msg) def _do(self, goal, func, *args, **kwds): title = func.task_title if goal in self.done: - self.info("already done: %s" % title) + self.log.info("already done: %s" % title) return else: - self.info("%s..." % title) + self.log.info("%s..." % title) func() if not func.task_idempotent: self.done[goal] = True @@ -114,7 +126,7 @@ # includes annotation and annotatation simplifications translator = self.translator policy = self.policy - self.info('with policy: %s.%s' % (policy.__class__.__module__, policy.__class__.__name__)) + self.log.info('with policy: %s.%s' % (policy.__class__.__module__, policy.__class__.__name__)) annmodel.DEBUG = self.options.debug annotator = translator.annotate(self.inputtypes, policy=policy) @@ -128,17 +140,17 @@ translator = self.translator irreg = query.qoutput(query.check_exceptblocks_qgen(translator)) if not irreg: - self.info("All exceptblocks seem sane") + self.log.info("All exceptblocks seem sane") lost = query.qoutput(query.check_methods_qgen(translator)) assert not lost, "lost methods, something gone wrong with the annotation of method defs" - self.info("No lost method defs") + self.log.info("No lost method defs") so = query.qoutput(query.polluted_qgen(translator)) tot = len(translator.flowgraphs) percent = int(tot and (100.0*so / tot) or 0) if percent == 0: - pr = self.info + pr = self.log.info else: pr = log.WARNING pr("-- someobjectness %2d%% (%d of %d functions polluted by SomeObjects)" % (percent, so, tot)) @@ -176,7 +188,7 @@ cbuilder = translator.cbuilder(standalone=standalone, gcpolicy=gcpolicy) c_source_filename = cbuilder.generate_source() - self.info("written: %s" % (c_source_filename,)) + self.log.info("written: %s" % (c_source_filename,)) self.cbuilder = cbuilder # task_source_c = taskdef(task_source_c, @@ -194,7 +206,7 @@ newexename = mkexename('./'+'pypy-c') shutil.copy(exename, newexename) self.c_entryp = newexename - self.info("created: %s" % (self.c_entryp,)) + self.log.info("created: %s" % (self.c_entryp,)) else: cbuilder.import_module() self.c_entryp = cbuilder.get_entry_point() @@ -243,7 +255,7 @@ genllvm.GcPolicy.new(opts.gc), genllvm.ExceptionPolicy.new(None)) self.llvm_filename = self.llvmgen.gen_llvm_source() - self.info("written: %s" % (self.llvm_filename,)) + self.log.info("written: %s" % (self.llvm_filename,)) # task_source_llvm = taskdef(task_source_llvm, ['backendopt', 'rtype'], @@ -270,7 +282,7 @@ if self.default_goal: goals = [self.default_goal] else: - self.info("nothing to do") + self.log.info("nothing to do") return elif isinstance(goals, str): goals = [goals] @@ -284,31 +296,22 @@ args = [] if options is None: options = DEFAULT_OPTIONS.copy() + + driver = TranslationDriver(options, default_goal, disable) target = targetspec_dic['target'] - try: - options.log = log - spec = target(options, args) - finally: - del options.log + spec = target(driver, args) + try: entry_point, inputtypes, policy = spec except ValueError: entry_point, inputtypes = spec policy = None - if empty_translator: - # re-initialize it - empty_translator.__init__(entry_point, verbose=True, simplifying=True) - translator = empty_translator - else: - translator = Translator(entry_point, verbose=True, simplifying=True) - - driver = TranslationDriver(translator, inputtypes, - policy, options, - disable=disable, - default_goal = default_goal, - extra = targetspec_dic) + driver.setup(entry_point, inputtypes, + policy=policy, + extra=targetspec_dic, + empty_translator=empty_translator) return driver Modified: pypy/dist/pypy/translator/goal/targetcompiler.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetcompiler.py (original) +++ pypy/dist/pypy/translator/goal/targetcompiler.py Sat Oct 1 15:44:51 2005 @@ -23,7 +23,9 @@ return 'target_ast_compile --> %r' % (pycode,) # _____ Define and setup target ___ -def target(options, args): +def target(driver, args): + options = driver.options + global space, w_entry_point geninterp = not getattr(options, 'lowmem', False) Modified: pypy/dist/pypy/translator/goal/targetpypymain.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypymain.py Sat Oct 1 15:44:51 2005 @@ -49,7 +49,9 @@ # _____ Define and setup target ___ -def target(options, args): +def target(driver, args): + options = driver.options + global space, w_entry_point geninterp = not getattr(options, 'lowmem', False) Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Sat Oct 1 15:44:51 2005 @@ -44,19 +44,16 @@ # _____ Define and setup target ___ -def target(options, args): +def target(driver, args): + options = driver.options + global space, w_entry_point geninterp = not getattr(options, 'lowmem', False) # obscure hack to stuff the translation options into the translated PyPy import pypy.module.sys - d = {} - for key, value in options.__dict__.items(): - if key == 'log': - continue - d[key.lstrip('-')] = value - wrapstr = 'space.wrap(%r)' % (d,) + wrapstr = 'space.wrap(%r)' % (options.__dict__) pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] = wrapstr # disable translation of the whole of classobjinterp.py From arigo at codespeak.net Sat Oct 1 16:08:53 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 16:08:53 +0200 (CEST) Subject: [pypy-svn] r18056 - pypy/dist/pypy/translator/test Message-ID: <20051001140853.2098B27C09@code1.codespeak.net> Author: arigo Date: Sat Oct 1 16:08:52 2005 New Revision: 18056 Removed: pypy/dist/pypy/translator/test/test_backends.py Log: Removed. There is little code here that we could reuse in a generic test of the new driver interface. From pedronis at codespeak.net Sat Oct 1 16:13:27 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 16:13:27 +0200 (CEST) Subject: [pypy-svn] r18057 - in pypy/dist/pypy/translator: goal tool Message-ID: <20051001141327.1438727C0C@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 16:13:25 2005 New Revision: 18057 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/tool/pdbplus.py Log: command graphserve to start serving graph at a later time 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 Sat Oct 1 16:13:25 2005 @@ -212,15 +212,23 @@ t = translator.Translator() - if options.graphserve: - from pypy.translator.tool.graphserver import run_async_server - serv_start, serv_show, serv_stop = run_async_server(t, options) - def server_setup(): - return serv_start, serv_show, serv_stop - else: - def server_setup(): - from pypy.translator.tool.graphserver import run_server_for_inprocess_client - return run_server_for_inprocess_client(t, options) + class ServerSetup: + async_server = None + + def __call__(self, port=None): + if self.async_server is not None: + return async_server + elif options.graphserve or port is not None: + if options.graphserve is None: + options.graphserve = port + from pypy.translator.tool.graphserver import run_async_server + serv_start, serv_show, serv_stop = self.async_server = run_async_server(t, options) + return serv_start, serv_show, serv_stop + else: + from pypy.translator.tool.graphserver import run_server_for_inprocess_client + return run_server_for_inprocess_client(t, options) + + server_setup = ServerSetup() pdb_plus_show = PdbPlusShow(t) # need a translator to support extended commands Modified: pypy/dist/pypy/translator/tool/pdbplus.py ============================================================================== --- pypy/dist/pypy/translator/tool/pdbplus.py (original) +++ pypy/dist/pypy/translator/tool/pdbplus.py Sat Oct 1 16:13:25 2005 @@ -1,7 +1,8 @@ import threading, pdb class _EnableGraphic: - pass + def __init__(self, port=None): + self.port = port class PdbPlusShow(pdb.Pdb): @@ -343,9 +344,19 @@ """enable_graphic enable pygame graph display even from non-graphic mode""" if self.show: + print "*** display already there" return raise _EnableGraphic + def do_graphserve(self, arg): + """graphserve +start serving graphs on +""" + if self.show: + print "*** display already there" + return + raise _EnableGraphic(int(arg)) + def help_graphs(self): print "graph commands are: showg, flowg, callg, classhier, enable_graphic" @@ -381,14 +392,15 @@ return threading.Thread(target=_run_in_thread, args=()) def start(self, tb, server_setup, graphic=False): + port = None if not graphic: try: self._run_debugger(tb) - except _EnableGraphic: - pass + except _EnableGraphic, engraph: + port = engraph.port else: return - start, show, stop = server_setup() + start, show, stop = server_setup(port) self.install_show(show) debugger = self._run_debugger_in_thread(tb, stop) debugger.start() From arigo at codespeak.net Sat Oct 1 16:24:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 16:24:27 +0200 (CEST) Subject: [pypy-svn] r18058 - pypy/dist/pypy/translator/goal Message-ID: <20051001142427.2489A27BC7@code1.codespeak.net> Author: arigo Date: Sat Oct 1 16:24:23 2005 New Revision: 18058 Modified: pypy/dist/pypy/translator/goal/driver.py Log: Crash early on SomeObjects for stand-alone targets. Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Sat Oct 1 16:24:23 2005 @@ -93,6 +93,8 @@ if policy is None: policy = annpolicy.AnnotatorPolicy() + if standalone: + policy.allow_someobjects = False self.policy = policy self.extra = extra From arigo at codespeak.net Sat Oct 1 16:43:00 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 16:43:00 +0200 (CEST) Subject: [pypy-svn] r18059 - pypy/dist/pypy/rpython/test Message-ID: <20051001144300.B655C27BC7@code1.codespeak.net> Author: arigo Date: Sat Oct 1 16:42:56 2005 New Revision: 18059 Modified: pypy/dist/pypy/rpython/test/test_normalizecalls.py Log: Added some tests here, in an attempt to find a bug that was elsewhere after all. Modified: pypy/dist/pypy/rpython/test/test_normalizecalls.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_normalizecalls.py (original) +++ pypy/dist/pypy/rpython/test/test_normalizecalls.py Sat Oct 1 16:42:56 2005 @@ -1,6 +1,8 @@ from pypy.annotation import model as annmodel from pypy.translator.translator import Translator from pypy.rpython.rtyper import RPythonTyper +from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython import lltype def rtype(fn, argtypes=[]): @@ -55,3 +57,67 @@ assert len(f1graph.getargs()) == 2 assert len(f2graph.getargs()) == 2 # normalized to the common call pattern #translator.view() + +def test_normalize_returnvar(): + def add_one(n): + return n+1 + def add_half(n): + return n+0.5 + def dummyfn(n, i): + if i == 1: + adder = add_one + else: + adder = add_half + return adder(n) + + res = interpret(dummyfn, [52, 1]) + assert type(res) is float and res == 53.0 + res = interpret(dummyfn, [7, 2]) + assert type(res) is float and res == 7.5 + +def test_normalize_missing_return(): + def add_one(n): + return n+1 + def oups(n): + raise ValueError + def dummyfn(n, i): + if i == 1: + adder = add_one + else: + adder = oups + try: + return adder(n) + except ValueError: + return -1 + + translator = rtype(dummyfn, [int, int]) + add_one_graph = translator.getflowgraph(add_one) + oups_graph = translator.getflowgraph(oups) + assert add_one_graph.getreturnvar().concretetype == lltype.Signed + assert oups_graph .getreturnvar().concretetype == lltype.Signed + #translator.view() + +def test_normalize_abstract_method(): + class Base: + def fn(self): + raise NotImplementedError + class Sub1(Base): + def fn(self): + return 1 + class Sub2(Base): + def fn(self): + return 2 + def dummyfn(n): + if n == 1: + x = Sub1() + else: + x = Sub2() + return x.fn() + + translator = rtype(dummyfn, [int]) + base_graph = translator.getflowgraph(Base.fn.im_func) + sub1_graph = translator.getflowgraph(Sub1.fn.im_func) + sub2_graph = translator.getflowgraph(Sub2.fn.im_func) + assert base_graph.getreturnvar().concretetype == lltype.Signed + assert sub1_graph.getreturnvar().concretetype == lltype.Signed + assert sub2_graph.getreturnvar().concretetype == lltype.Signed From arigo at codespeak.net Sat Oct 1 16:43:25 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 16:43:25 +0200 (CEST) Subject: [pypy-svn] r18060 - in pypy/dist/pypy: rpython rpython/test translator/c/test Message-ID: <20051001144325.9DE5D27BC7@code1.codespeak.net> Author: arigo Date: Sat Oct 1 16:43:17 2005 New Revision: 18060 Modified: pypy/dist/pypy/rpython/rfloat.py pypy/dist/pypy/rpython/test/test_rfloat.py pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Clean up the support for str(float) in RPython. Modified: pypy/dist/pypy/rpython/rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/rfloat.py (original) +++ pypy/dist/pypy/rpython/rfloat.py Sat Oct 1 16:43:17 2005 @@ -5,7 +5,7 @@ from pypy.rpython.rmodel import IntegerRepr, BoolRepr from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.lltype import PyObject, Array, Char -from pypy.rpython.rstr import STR +from pypy.rpython.rstr import STR, string_repr from pypy.rpython.lltype import functionptr, FuncType, malloc from pypy.rpython import rstr from pypy.rpython.rmodel import log @@ -135,31 +135,10 @@ rtype_float = rtype_pos def ll_str(self, f): - pyfloat = pyfloat_fromdouble_ptr(f) - pystring = pyobject_str_ptr(pyfloat) - stringsize = pystring_size_ptr(pystring) - - ret = malloc(STR, stringsize) - - tollchararray_ptr(pystring, ret.chars) - - return ret - -PyObjectPtr = Ptr(PyObject) - -pystring_size_ptr = functionptr(FuncType([PyObjectPtr], Signed), - "PyString_Size", - external="C") -pyfloat_fromdouble_ptr = functionptr(FuncType([Float], PyObjectPtr), - "PyFloat_FromDouble", - external="C") -pyobject_str_ptr = functionptr(FuncType([PyObjectPtr], PyObjectPtr), - "PyObject_Str", - external="C") -tollchararray_ptr = functionptr(FuncType([PyObjectPtr, Ptr(Array(Char))], Void), - "PyString_ToLLCharArray", - external="C") - + from pypy.rpython.module.ll_strtod import ll_strtod_formatd + return ll_strtod_formatd(percent_f, f) + +percent_f = string_repr.convert_const("%f") # # _________________________ Conversions _________________________ Modified: pypy/dist/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rfloat.py (original) +++ pypy/dist/pypy/rpython/test/test_rfloat.py Sat Oct 1 16:43:17 2005 @@ -47,3 +47,10 @@ assert type(res) is int res = interpret(fn, [2.34]) assert res == fn(2.34) + +def test_float2str(): + def fn(f): + return str(f) + + res = interpret(fn, [1.5]) + assert ''.join(res.chars) == '%f' % 1.5 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 Sat Oct 1 16:43:17 2005 @@ -304,6 +304,12 @@ assert f(1.5) == "1.50" assert f(2.0) == "2.00" +def test_rarith_float_to_str(): + def fn(f): + return str(f) + f = compile(fn, [float]) + assert f(1.5) == '%f' % 1.5 + def test_lock(): import thread import pypy.module.thread.rpython.exttable # for declare()/declaretype() From arigo at codespeak.net Sat Oct 1 18:05:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 18:05:46 +0200 (CEST) Subject: [pypy-svn] r18061 - pypy/dist/pypy/translator/c Message-ID: <20051001160546.29E1927BA7@code1.codespeak.net> Author: arigo Date: Sat Oct 1 18:05:45 2005 New Revision: 18061 Modified: pypy/dist/pypy/translator/c/genc.py Log: Include CPython's pyconfig before any other header, for the #define tweaks it provides. Note that we cannot include the whole of Python.h before gc.h in the presence of thread. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sat Oct 1 18:05:45 2005 @@ -206,6 +206,7 @@ for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) + print >> f, '#include "pyconfig.h"' for line in database.gcpolicy.pre_pre_gc_code(): print >> f, line @@ -245,6 +246,7 @@ for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) + print >> f, '#include "pyconfig.h"' for line in database.gcpolicy.pre_pre_gc_code(): print >> f, line From tismer at codespeak.net Sat Oct 1 18:26:47 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 1 Oct 2005 18:26:47 +0200 (CEST) Subject: [pypy-svn] r18062 - pypy/extradoc/talk/22c3 Message-ID: <20051001162647.2935E27BA7@code1.codespeak.net> Author: tismer Date: Sat Oct 1 18:26:45 2005 New Revision: 18062 Modified: pypy/extradoc/talk/22c3/speaker-beatriceduering.txt (contents, props changed) pypy/extradoc/talk/22c3/speaker-carlfriedrichbolz.txt (props changed) pypy/extradoc/talk/22c3/talk-os-business.txt (contents, props changed) Log: eolstyle:native Modified: pypy/extradoc/talk/22c3/speaker-beatriceduering.txt ============================================================================== --- pypy/extradoc/talk/22c3/speaker-beatriceduering.txt (original) +++ pypy/extradoc/talk/22c3/speaker-beatriceduering.txt Sat Oct 1 18:26:45 2005 @@ -1,47 +1,47 @@ -Reference/Call For Papers: http://www.ccc.de/congress/2005/cfp.html -DEADLINE: 30th September 2005 (friday) - -Name: Beatrice D?ring - -Public Name: Beatrice D?ring - -Other Names: bd on irc.freenode.org, bea - -Primary E-Mail address: bea at changemaker.nu - -Phone number(s): +46 (0)734 22 89 06 - -A photo, square format, min. 128x128 pixels (optional): - (is also attached in the proposals zip file) - see http://codespeak.net/pypy/extradoc/talk/22C3/bea.jpg - -Statement: publishing contact info except for the phone number - is fine with me. - -Public home page, weblog and other speaker-related websites: - - http://codespeak.net/pypy - -Short Info: - - Beatrice During (Sweden), consultant in the project management field, - assistant project manager in PyPy - -Bio: - - Beatrice D?ring studied teaching/pedagogy at the University of Karlstad in - Sweden. She was recruited into the IT-industry to work as a project manager - for large scale education projects for the company NetGuide Scandinavia, - Gothenburg. Since 1998 she has been working with education and development - project management and management of education and consultant departments, - implementing Open Source strategies and Agile development methods. Beatrice - also teaches project management, requirements and communication courses for - Learning Tree International through the Chaos Pilot company Change Maker. - Currently she is involved in the project management team of the PyPy project - and tries to fit in some maternity leave (;-) - - -Postal address: Change Maker, J?rntorget 3, 41304 Gothenburg, Sweden -Bank information: -Expected day of arrival and departure: 27th-30th December. - +Reference/Call For Papers: http://www.ccc.de/congress/2005/cfp.html +DEADLINE: 30th September 2005 (friday) + +Name: Beatrice D?ring + +Public Name: Beatrice D?ring + +Other Names: bd on irc.freenode.org, bea + +Primary E-Mail address: bea at changemaker.nu + +Phone number(s): +46 (0)734 22 89 06 + +A photo, square format, min. 128x128 pixels (optional): + (is also attached in the proposals zip file) + see http://codespeak.net/pypy/extradoc/talk/22C3/bea.jpg + +Statement: publishing contact info except for the phone number + is fine with me. + +Public home page, weblog and other speaker-related websites: + + http://codespeak.net/pypy + +Short Info: + + Beatrice During (Sweden), consultant in the project management field, + assistant project manager in PyPy + +Bio: + + Beatrice D?ring studied teaching/pedagogy at the University of Karlstad in + Sweden. She was recruited into the IT-industry to work as a project manager + for large scale education projects for the company NetGuide Scandinavia, + Gothenburg. Since 1998 she has been working with education and development + project management and management of education and consultant departments, + implementing Open Source strategies and Agile development methods. Beatrice + also teaches project management, requirements and communication courses for + Learning Tree International through the Chaos Pilot company Change Maker. + Currently she is involved in the project management team of the PyPy project + and tries to fit in some maternity leave (;-) + + +Postal address: Change Maker, J?rntorget 3, 41304 Gothenburg, Sweden +Bank information: +Expected day of arrival and departure: 27th-30th December. + Modified: pypy/extradoc/talk/22c3/talk-os-business.txt ============================================================================== --- pypy/extradoc/talk/22c3/talk-os-business.txt (original) +++ pypy/extradoc/talk/22c3/talk-os-business.txt Sat Oct 1 18:26:45 2005 @@ -1,63 +1,63 @@ -Reference/Call For Papers: http://www.ccc.de/congress/2005/cfp.html -DEADLINE: 31st September 2005 (friday) - -Title: agile open-source methods <-> business/EU-funding - -Subtitle: Sprint driven development in Open Source projects - - agile methods in open-source related companies - -Section: Hacker(ethik), (or Culture? or Community?) - -Talkers: Beatrice D?ring, Holger Krekel - -Abstract (max 250 letters): - - There is a growing number of open-source developers - organized and connected to company and money related work. - We report our experiences from the first year of the PyPy - project which has a 7 company/university consortium and a - 1.3 Million Euro research grant from the European Union. - -Description (250-500 words): - - We'd like to present and discuss models and experiences - for connecting open-source/hacking culture driven development - to money related projects and goals with the audience. - - We are going to briefly describe the organisation of the PyPy project, - showing how formal stakeholders and OSS Python community interact - through agile practices like sprinting. We will also reflect on the - aspect of diversity, combining technical and non technical people and - skills and learnings from this. - - We will relate the various agile techniques used in PyPy - and other projects/companies to the agile practices known from - the work in the Agile Alliance (XP, Scrum, Crystal) and tell - you what we know of how other projects are doing it. - - Lastly we will also share our experience of various challenges and - possibilities when integrating the different cultures and skills from - the OSS perspective, EU perspective and the Chaos Pilot/process management - perspective - managing diversities. - -Statement: We intend to submit a paper (PDF) for the 22C3 proceedings. -Statement: We intend to submit a slides PDF as well. - -Duration of your talk: 45 minutes + questions - -Language of your talk: english - -Links to background information on the talk: - http://codespeak.net/pypy/dist/pypy/doc/dev_method.html - http://codespeak.net/pypy/dist/pypy - -Target Group: Advanced Users, Pros - -Resources you need for your talk: digital projector, internet - -Related talks at 22C3 you know of: PyPy - the new Python implementation on the block - -A lecture logo, square format, min. 128x128 pixels (optional): - http://codespeak.net/pypy/img/py-web1.png - (please scale it down a bit :-) - +Reference/Call For Papers: http://www.ccc.de/congress/2005/cfp.html +DEADLINE: 31st September 2005 (friday) + +Title: agile open-source methods <-> business/EU-funding + +Subtitle: Sprint driven development in Open Source projects - + agile methods in open-source related companies + +Section: Hacker(ethik), (or Culture? or Community?) + +Talkers: Beatrice D?ring, Holger Krekel + +Abstract (max 250 letters): + + There is a growing number of open-source developers + organized and connected to company and money related work. + We report our experiences from the first year of the PyPy + project which has a 7 company/university consortium and a + 1.3 Million Euro research grant from the European Union. + +Description (250-500 words): + + We'd like to present and discuss models and experiences + for connecting open-source/hacking culture driven development + to money related projects and goals with the audience. + + We are going to briefly describe the organisation of the PyPy project, + showing how formal stakeholders and OSS Python community interact + through agile practices like sprinting. We will also reflect on the + aspect of diversity, combining technical and non technical people and + skills and learnings from this. + + We will relate the various agile techniques used in PyPy + and other projects/companies to the agile practices known from + the work in the Agile Alliance (XP, Scrum, Crystal) and tell + you what we know of how other projects are doing it. + + Lastly we will also share our experience of various challenges and + possibilities when integrating the different cultures and skills from + the OSS perspective, EU perspective and the Chaos Pilot/process management + perspective - managing diversities. + +Statement: We intend to submit a paper (PDF) for the 22C3 proceedings. +Statement: We intend to submit a slides PDF as well. + +Duration of your talk: 45 minutes + questions + +Language of your talk: english + +Links to background information on the talk: + http://codespeak.net/pypy/dist/pypy/doc/dev_method.html + http://codespeak.net/pypy/dist/pypy + +Target Group: Advanced Users, Pros + +Resources you need for your talk: digital projector, internet + +Related talks at 22C3 you know of: PyPy - the new Python implementation on the block + +A lecture logo, square format, min. 128x128 pixels (optional): + http://codespeak.net/pypy/img/py-web1.png + (please scale it down a bit :-) + From arigo at codespeak.net Sat Oct 1 18:37:59 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 18:37:59 +0200 (CEST) Subject: [pypy-svn] r18063 - in pypy/dist/pypy: rpython translator/c translator/c/src Message-ID: <20051001163759.7DCBA27B9E@code1.codespeak.net> Author: arigo Date: Sat Oct 1 18:37:58 2005 New Revision: 18063 Modified: pypy/dist/pypy/rpython/lltype.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/src/mem.h Log: (pedronis, arigo) Another interesting performance boost, by producing more precise mallocs for Boehm: * refine the condition under which a malloced object contains no pointer to track; * for allocating arrays, use a malloc variant that knows that the array can be huge but that there are no pointer from outside into the *middle* of the array data; * the non-atomic variants of Boehm's malloc already guarantee that the result is zero-initialized. Modified: pypy/dist/pypy/rpython/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltype.py (original) +++ pypy/dist/pypy/rpython/lltype.py Sat Oct 1 18:37:58 2005 @@ -113,6 +113,9 @@ def _is_atomic(self): return False + def _is_varsize(self): + return False + class ContainerType(LowLevelType): def _gcstatus(self): @@ -174,6 +177,9 @@ return False return True + def _is_varsize(self): + return self._arrayfld is not None + def __getattr__(self, name): try: return self._flds[name] @@ -256,6 +262,9 @@ def _is_atomic(self): return self.OF._is_atomic() + def _is_varsize(self): + return True + def _str_fields(self): if isinstance(self.OF, Struct): of = self.OF @@ -403,6 +412,8 @@ def _short_name(self): return 'Ptr %s' % (self.TO._short_name(), ) + def _is_atomic(self): + return not self.TO._gcstatus() def _defl(self, parent=None, parentindex=None): return _ptr(self, None) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Sat Oct 1 18:37:58 2005 @@ -2,7 +2,7 @@ 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 GcArray, GcStruct +from pypy.rpython.lltype import Array, GcArray, Struct, GcStruct from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo PyObjPtr = Ptr(PyObject) @@ -252,6 +252,7 @@ # zero malloc impl def zero_malloc(self, TYPE, esize, eresult, err): + assert TYPE._gcstatus() # we don't really support this return 'OP_ZERO_MALLOC(%s, %s, %s);' % (esize, eresult, err) @@ -338,18 +339,18 @@ def zero_malloc(self, TYPE, esize, eresult, err): gcinfo = self.db.gettypedefnode(TYPE).gcinfo - atomic = ['','_ATOMIC'][TYPE._is_atomic()] + assert TYPE._gcstatus() # _is_atomic() depends on this! + is_atomic = TYPE._is_atomic() + is_varsize = TYPE._is_varsize() + result = 'OP_BOEHM_ZERO_MALLOC(%s, %s, %d, %d, %s);' % (esize, + eresult, + is_atomic, + is_varsize, + err) if gcinfo and gcinfo.finalizer: - return '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, %s);' % (esize, - eresult, - atomic, - err) + result += ('\tGC_REGISTER_FINALIZER(%s, %s, NULL, NULL, NULL);' + % (eresult, gcinfo.finalizer)) + return result 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 Sat Oct 1 18:37:58 2005 @@ -49,17 +49,16 @@ #ifdef USING_BOEHM_GC -#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 BOEHM_MALLOC_0_0 GC_MALLOC +#define BOEHM_MALLOC_1_0 GC_MALLOC_ATOMIC +#define BOEHM_MALLOC_0_1 GC_MALLOC_IGNORE_OFF_PAGE +#define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE -#define OP_BOEHM_ZERO_MALLOC_FINALIZER(size, r, atomic, finalizer, err) { \ - r = (void*) GC_MALLOC##atomic(size); \ +#define OP_BOEHM_ZERO_MALLOC(size, r, is_atomic, is_varsize, err) { \ + r = (void*) BOEHM_MALLOC_ ## is_atomic ## _ ## is_varsize (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); \ + if (is_atomic) /* the non-atomic versions return cleared memory */ \ + memset((void*) r, 0, size); \ } #undef PUSH_ALIVE From arigo at codespeak.net Sat Oct 1 18:44:33 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 18:44:33 +0200 (CEST) Subject: [pypy-svn] r18064 - in pypy/dist/pypy: rpython/test translator/c/test Message-ID: <20051001164433.982D027B9E@code1.codespeak.net> Author: arigo Date: Sat Oct 1 18:44:32 2005 New Revision: 18064 Modified: pypy/dist/pypy/rpython/test/test_rfloat.py pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Tests too precise. Modified: pypy/dist/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rfloat.py (original) +++ pypy/dist/pypy/rpython/test/test_rfloat.py Sat Oct 1 18:44:32 2005 @@ -53,4 +53,4 @@ return str(f) res = interpret(fn, [1.5]) - assert ''.join(res.chars) == '%f' % 1.5 + assert eval(''.join(res.chars)) == 1.5 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 Sat Oct 1 18:44:32 2005 @@ -308,7 +308,8 @@ def fn(f): return str(f) f = compile(fn, [float]) - assert f(1.5) == '%f' % 1.5 + res = f(1.5) + assert eval(res) == 1.5 def test_lock(): import thread From tismer at codespeak.net Sat Oct 1 20:35:52 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 1 Oct 2005 20:35:52 +0200 (CEST) Subject: [pypy-svn] r18068 - pypy/extradoc/talk/22c3 Message-ID: <20051001183552.0CBEF27B96@code1.codespeak.net> Author: tismer Date: Sat Oct 1 20:35:51 2005 New Revision: 18068 Added: pypy/extradoc/talk/22c3/christian_tismer.jpg (contents, props changed) pypy/extradoc/talk/22c3/speaker-christiantismer.txt (contents, props changed) Log: added speaker info, just in case Added: pypy/extradoc/talk/22c3/christian_tismer.jpg ============================================================================== Binary file. No diff available. Added: pypy/extradoc/talk/22c3/speaker-christiantismer.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/22c3/speaker-christiantismer.txt Sat Oct 1 20:35:51 2005 @@ -0,0 +1,43 @@ +Reference/Call For Papers: http://www.ccc.de/congress/2005/cfp.html +DEADLINE: 30th September 2005 (friday) + +Name: Christian Tismer + +Public Name: Christian Tismer + +Other Names: stakkars on irc.freenode.org + +Primary E-Mail address: tismer at stackless.com + +Phone number(s): +49 173 24 18 776 + +A photo, square format, min. 128x128 pixels (optional): + http://codespeak.net/pypy/extradoc/talk/22C3/christian_tismer.jpg + +Statement: publishing contact info except for the phone number + is fine with me. + +Public home page, weblog and other speaker-related websites: + + http://codespeak.net/pypy + http://www.stackless.com + +Short Info: + + Christian Tismer, co-founder and developer of PyPy, CEO tismerysoft GmbH. + +Bio: + + Christian studied math, physics and IS at the Free University of Berlin. + He spent a decade on pharmaceutical research, generating reports, doing + EEG recording software, power spectra analysis and wavelet transforms. + He then became a software consultant, and invented Stackless Python + which he continues to maintain until it becomes obsolete by PyPy. + He founded tismerysoft in 2004 with the intent to participate in + PyPy as a core developer and to build applications and consulting + services on top of PyPy. + +Postal address: tismerysoft GmbH, Christian Tismer, Johannes-Niemeyer-Weg 9A, 14109 Berlin +Bank information: +Expected day of arrival and departure: 27th-30th December. + From pedronis at codespeak.net Sat Oct 1 20:48:12 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 20:48:12 +0200 (CEST) Subject: [pypy-svn] r18069 - pypy/dist/pypy/translator/goal Message-ID: <20051001184812.D012B27B96@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 20:48:11 2005 New Revision: 18069 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: oops, async_server should be started at the beginning 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 Sat Oct 1 20:48:11 2005 @@ -229,6 +229,9 @@ return run_server_for_inprocess_client(t, options) server_setup = ServerSetup() + if options.grapserv: + server_setup() + pdb_plus_show = PdbPlusShow(t) # need a translator to support extended commands From pedronis at codespeak.net Sat Oct 1 20:48:35 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 20:48:35 +0200 (CEST) Subject: [pypy-svn] r18070 - pypy/dist/pypy/translator/goal Message-ID: <20051001184835.72EBC27B96@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 20:48:34 2005 New Revision: 18070 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: oops * 2 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 Sat Oct 1 20:48:34 2005 @@ -229,7 +229,7 @@ return run_server_for_inprocess_client(t, options) server_setup = ServerSetup() - if options.grapserv: + if options.grapserve: server_setup() From pedronis at codespeak.net Sat Oct 1 20:49:50 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 20:49:50 +0200 (CEST) Subject: [pypy-svn] r18071 - pypy/dist/pypy/translator/goal Message-ID: <20051001184950.F16C127B96@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 20:49:48 2005 New Revision: 18071 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: oops * 3 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 Sat Oct 1 20:49:48 2005 @@ -229,7 +229,7 @@ return run_server_for_inprocess_client(t, options) server_setup = ServerSetup() - if options.grapserve: + if options.graphserve: server_setup() From pedronis at codespeak.net Sat Oct 1 20:53:04 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 20:53:04 +0200 (CEST) Subject: [pypy-svn] r18072 - pypy/dist/pypy/translator/goal Message-ID: <20051001185304.3756127B96@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 20:53:02 2005 New Revision: 18072 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: oops * 4 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 Sat Oct 1 20:53:02 2005 @@ -217,7 +217,7 @@ def __call__(self, port=None): if self.async_server is not None: - return async_server + return self.async_server elif options.graphserve or port is not None: if options.graphserve is None: options.graphserve = port From pedronis at codespeak.net Sat Oct 1 21:50:03 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 21:50:03 +0200 (CEST) Subject: [pypy-svn] r18073 - pypy/dist/pypy/translator/goal Message-ID: <20051001195003.14C3027B86@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 21:50:02 2005 New Revision: 18073 Modified: pypy/dist/pypy/translator/goal/bench-unix.py Log: accomodate changes done to richards.py Modified: pypy/dist/pypy/translator/goal/bench-unix.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-unix.py (original) +++ pypy/dist/pypy/translator/goal/bench-unix.py Sat Oct 1 21:50:02 2005 @@ -19,8 +19,8 @@ PYSTONE_CMD = 'from test import pystone;pystone.main(%s)' PYSTONE_PATTERN = 'This machine benchmarks at' -RICHARDS_CMD = 'from richards import *;Richards.iterations=%d;main()' -RICHARDS_PATTERN = 'Average time for iterations:' +RICHARDS_CMD = 'from richards import *;main(iterations=%d)' +RICHARDS_PATTERN = 'Average time per iteration:' def get_result(txt, pattern): for line in txt.split('\n'): From pedronis at codespeak.net Sat Oct 1 21:52:12 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 21:52:12 +0200 (CEST) Subject: [pypy-svn] r18074 - pypy/dist/pypy/translator/goal Message-ID: <20051001195212.5D49F27B86@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 21:52:11 2005 New Revision: 18074 Modified: pypy/dist/pypy/translator/goal/bench-windows.py Log: accomodate changes to richards.py Modified: pypy/dist/pypy/translator/goal/bench-windows.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-windows.py (original) +++ pypy/dist/pypy/translator/goal/bench-windows.py Sat Oct 1 21:52:11 2005 @@ -36,8 +36,8 @@ PYSTONE_CMD = 'from test import pystone;pystone.main(%s)' PYSTONE_PATTERN = 'This machine benchmarks at' -RICHARDS_CMD = 'from richards import *;Richards.iterations=%d;main()' -RICHARDS_PATTERN = 'Average time for iterations:' +RICHARDS_CMD = 'from richards import *;main(iterations=%d)' +RICHARDS_PATTERN = 'Average time per iteration:' def get_result(txt, pattern): for line in txt.split('\n'): From arigo at codespeak.net Sat Oct 1 21:52:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 1 Oct 2005 21:52:27 +0200 (CEST) Subject: [pypy-svn] r18075 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20051001195227.A3A4B27B86@code1.codespeak.net> Author: arigo Date: Sat Oct 1 21:52:22 2005 New Revision: 18075 Modified: pypy/dist/pypy/objspace/std/default.py pypy/dist/pypy/objspace/std/test/test_intobject.py Log: Use getname() here too. Modified: pypy/dist/pypy/objspace/std/default.py ============================================================================== --- pypy/dist/pypy/objspace/std/default.py (original) +++ pypy/dist/pypy/objspace/std/default.py Sat Oct 1 21:52:22 2005 @@ -17,9 +17,8 @@ pass def typed_unwrap_error_msg(space, expected, w_obj): - w = space.wrap - type_name = space.str_w(space.getattr(space.type(w_obj),w("__name__"))) - return w("expected %s, got %s object" % (expected, type_name)) + type_name = space.type(w_obj).getname(space, '?') + return space.wrap("expected %s, got %s object" % (expected, type_name)) def int_w__ANY(space,w_obj): raise OperationError(space.w_TypeError, Modified: pypy/dist/pypy/objspace/std/test/test_intobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/test/test_intobject.py (original) +++ pypy/dist/pypy/objspace/std/test/test_intobject.py Sat Oct 1 21:52:22 2005 @@ -314,6 +314,7 @@ assert 42 == int('2A', 16) assert 42 == int('42', 10) raises(TypeError, int, 1, 10) + raises(TypeError, int, '5', '9') def test_shift_zeros(self): assert (1 << 0) == 1 From pedronis at codespeak.net Sat Oct 1 23:27:29 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 1 Oct 2005 23:27:29 +0200 (CEST) Subject: [pypy-svn] r18076 - in pypy/dist/pypy/translator: goal tool Message-ID: <20051001212729.5300527BA9@code1.codespeak.net> Author: pedronis Date: Sat Oct 1 23:27:27 2005 New Revision: 18076 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/tool/graphserver.py Log: small cleanup 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 Sat Oct 1 23:27:27 2005 @@ -215,23 +215,19 @@ class ServerSetup: async_server = None - def __call__(self, port=None): + def __call__(self, port=None, async_only=False): if self.async_server is not None: return self.async_server - elif options.graphserve or port is not None: - if options.graphserve is None: - options.graphserve = port + elif port is not None: from pypy.translator.tool.graphserver import run_async_server - serv_start, serv_show, serv_stop = self.async_server = run_async_server(t, options) + serv_start, serv_show, serv_stop = self.async_server = run_async_server(t, options, port) return serv_start, serv_show, serv_stop - else: + elif not async_only: from pypy.translator.tool.graphserver import run_server_for_inprocess_client return run_server_for_inprocess_client(t, options) server_setup = ServerSetup() - if options.graphserve: - server_setup() - + server_setup(options.graphserve, async_only=True) pdb_plus_show = PdbPlusShow(t) # need a translator to support extended commands Modified: pypy/dist/pypy/translator/tool/graphserver.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphserver.py (original) +++ pypy/dist/pypy/translator/tool/graphserver.py Sat Oct 1 23:27:27 2005 @@ -10,10 +10,10 @@ send_msg = portutil.send_msg recv_msg = portutil.recv_msg -def run_async_server(t, options): +def run_async_server(t, options, port): import graphpage homepage = graphpage.TranslatorPage(t, options.huge) - return run_server(homepage, port=options.graphserve, background=True) + return run_server(homepage, port=port, background=True) class GraphserverPort(portutil.Port): From arigo at codespeak.net Sun Oct 2 12:27:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 12:27:12 +0200 (CEST) Subject: [pypy-svn] r18077 - pypy/dist/pypy/translator/c/src Message-ID: <20051002102712.1074227BA9@code1.codespeak.net> Author: arigo Date: Sun Oct 2 12:27:07 2005 New Revision: 18077 Modified: pypy/dist/pypy/translator/c/src/main.h Log: Bug in the start-up error reporting logic. 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 Sun Oct 2 12:27:07 2005 @@ -6,17 +6,17 @@ int main(int argc, char *argv[]) { - char *errmsg = "out of memory"; + char *errmsg; int i, exitcode; RPyListOfString *list; errmsg = RPython_StartupCode(); if (errmsg) goto error; list = _RPyListOfString_New(argc); - if (RPyExceptionOccurred()) goto error; + if (RPyExceptionOccurred()) goto memory_out; for (i=0; i Author: arigo Date: Sun Oct 2 12:30:50 2005 New Revision: 18078 Modified: pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/src/mem.h Log: Trying to disable all interior pointer detection in Boehm. In theory we should always have a pointer to the beginning of every GcStruct and GcArray. A potential problem is that C compilers might introduce optimizations that make this assumption invalid. We couldn't produce such a case with gcc, though. We already did this for arrays; this check-in does it globally (which means for structs as well). If we start getting obscure segfaults with non-gcc compilers we know that we need to try to re-enable GC_interior_pointers. Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Sun Oct 2 12:30:50 2005 @@ -363,6 +363,7 @@ yield '#define USING_BOEHM_GC' def gc_startup_code(self): + yield 'GC_all_interior_pointers = 0;' yield 'GC_INIT();' 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 Sun Oct 2 12:30:50 2005 @@ -51,8 +51,10 @@ #define BOEHM_MALLOC_0_0 GC_MALLOC #define BOEHM_MALLOC_1_0 GC_MALLOC_ATOMIC -#define BOEHM_MALLOC_0_1 GC_MALLOC_IGNORE_OFF_PAGE -#define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE +#define BOEHM_MALLOC_0_1 GC_MALLOC +#define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC +/* #define BOEHM_MALLOC_0_1 GC_MALLOC_IGNORE_OFF_PAGE */ +/* #define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE */ #define OP_BOEHM_ZERO_MALLOC(size, r, is_atomic, is_varsize, err) { \ r = (void*) BOEHM_MALLOC_ ## is_atomic ## _ ## is_varsize (size); \ From arigo at codespeak.net Sun Oct 2 13:21:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 13:21:23 +0200 (CEST) Subject: [pypy-svn] r18079 - pypy/dist/pypy/translator/tool Message-ID: <20051002112123.8B6E227B73@code1.codespeak.net> Author: arigo Date: Sun Oct 2 13:21:22 2005 New Revision: 18079 Modified: pypy/dist/pypy/translator/tool/cbuild.py Log: Hack the -O2 option to gcc in build_executable(). Otherwise, distutils makes a non-optimized build :-( Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Sun Oct 2 13:21:22 2005 @@ -253,7 +253,7 @@ if sys.platform != 'win32': libraries.append('m') libraries.append('pthread') - extra_preargs = ['-pthread'] # XXX make this more general + extra_preargs = ['-O2', '-pthread'] # XXX 2 x hackish if outputfilename is None: outputfilename = py.path.local(cfilenames[0]).new(ext=ext) else: From arigo at codespeak.net Sun Oct 2 15:16:41 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 15:16:41 +0200 (CEST) Subject: [pypy-svn] r18080 - pypy/dist/pypy/translator/tool Message-ID: <20051002131641.A086627B8A@code1.codespeak.net> Author: arigo Date: Sun Oct 2 15:16:38 2005 New Revision: 18080 Modified: pypy/dist/pypy/translator/tool/cbuild.py Log: Log the invoked compiler commands. Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Sun Oct 2 15:16:38 2005 @@ -1,10 +1,13 @@ import autopath -import py - import os, sys, inspect, re, imp from pypy.translator.tool import stdoutcapture +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("cbuild") +py.log.setconsumer("cbuild", ansi_log) + debug = 0 def make_module_from_pyxstring(name, dirpath, string): @@ -245,6 +248,12 @@ return getattr(mod, func.func_name) +def log_spawned_cmd(spawn): + def spawn_and_log(cmd, *args, **kwds): + log.execute(' '.join(cmd)) + return spawn(cmd, *args, **kwds) + return spawn_and_log + def build_executable(cfilenames, outputfilename=None, include_dirs=None, libraries=[]): from distutils.ccompiler import new_compiler @@ -259,7 +268,8 @@ else: outputfilename = py.path.local(outputfilename) - compiler = new_compiler() + compiler = new_compiler() + compiler.spawn = log_spawned_cmd(compiler.spawn) objects = [] for cfile in cfilenames: cfile = py.path.local(cfile) From tismer at codespeak.net Sun Oct 2 18:31:05 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 2 Oct 2005 18:31:05 +0200 (CEST) Subject: [pypy-svn] r18083 - pypy/dist/pypy/objspace/flow Message-ID: <20051002163105.7003027B7B@code1.codespeak.net> Author: tismer Date: Sun Oct 2 18:31:04 2005 New Revision: 18083 Modified: pypy/dist/pypy/objspace/flow/model.py Log: no longer counting variable objects. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Sun Oct 2 18:31:04 2005 @@ -27,8 +27,6 @@ Probably an effect of less fragmentation. """ -COUNTOBJECTS = False - __metaclass__ = type class roproperty(object): @@ -214,9 +212,6 @@ __slots__ = ["_name", "concretetype"] countall = 0 - if COUNTOBJECTS: - countmax = 0 - countcurr = 0 def name(self): name = self._name @@ -232,16 +227,9 @@ def __init__(self, name=None): self._name = Variable.countall Variable.countall += 1 - if COUNTOBJECTS: - Variable.countcurr += 1 - Variable.countmax = max(Variable.countmax, Variable.countcurr) if name is not None: self.rename(name) - if COUNTOBJECTS: - def __del__(self): - Variable.countcurr -= 1 - def __repr__(self): return '%s' % self.name @@ -279,9 +267,6 @@ if type(_name) is int: if _name > Variable.countall: Variable.countall = _name - if COUNTOBJECTS: - Variable.countcurr += 1 - Variable.countmax = max(Variable.countmax, Variable.countcurr) return v class Constant(Hashable): From arigo at codespeak.net Sun Oct 2 18:45:34 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 18:45:34 +0200 (CEST) Subject: [pypy-svn] r18084 - in pypy/dist/pypy/tool/math: . test Message-ID: <20051002164534.AF0FD27B7B@code1.codespeak.net> Author: arigo Date: Sun Oct 2 18:45:26 2005 New Revision: 18084 Added: pypy/dist/pypy/tool/math/ pypy/dist/pypy/tool/math/__init__.py - copied unchanged from r18079, pypy/dist/pypy/tool/__init__.py pypy/dist/pypy/tool/math/graphlib.py (contents, props changed) pypy/dist/pypy/tool/math/sparsemat.py - copied unchanged from r18079, pypy/dist/pypy/translator/backendopt/sparsemat.py pypy/dist/pypy/tool/math/test/ pypy/dist/pypy/tool/math/test/__init__.py - copied unchanged from r18079, pypy/dist/pypy/tool/__init__.py pypy/dist/pypy/tool/math/test/test_graphlib.py (contents, props changed) pypy/dist/pypy/tool/math/unionfind.py - copied unchanged from r18079, pypy/dist/pypy/tool/unionfind.py Log: Intermediate check-in, see next one. Added: pypy/dist/pypy/tool/math/graphlib.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/math/graphlib.py Sun Oct 2 18:45:26 2005 @@ -0,0 +1,107 @@ +""" +Utilities to manipulate graphs (vertices and edges, not control flow graphs). +""" + +class Edge: + def __init__(self, source, target): + self.source = source + self.target = target + +def depth_first_search(root, vertices, edges): + seen = {} + result = [] + def visit(vertex): + result.append(('start', vertex)) + seen[vertex] = True + for edge in edges[vertex]: + w = edge.target + if w in vertices and w not in seen: + visit(w) + result.append(('stop', vertex)) + visit(root) + return result + +def strong_components(vertices, edges): + """Enumerates the strongly connected components of a graph. Each one is + a set of vertices where any node can be reached from any other vertex by + following the edges. 'edges' is a dict {vertex: [edges]})""" + + component_root = {} + discovery_time = {} + stack = [] + + for root in vertices: + if root not in discovery_time: + + for event, v in depth_first_search(root, vertices, edges): + if event == 'start': + discovery_time[v] = len(discovery_time) + component_root[v] = v + stack.append(v) + + else: # event == 'stop' + vroot = v + for edge in edges[v]: + w = edge.target + if w in component_root: + wroot = component_root[w] + if discovery_time[wroot] < discovery_time[vroot]: + vroot = wroot + if vroot is v: + component = {} + while True: + w = stack.pop() + del component_root[w] + component[w] = True + if w is v: + break + yield component + else: + component_root[v] = vroot + +def all_cycles(root, vertices, edges): + """Enumerates cycles. Each cycle is a list of edges.""" + stackpos = {} + edgestack = [] + result = [] + def visit(v): + if v not in stackpos: + stackpos[v] = len(edgestack) + for edge in edges[v]: + if edge.target in vertices: + edgestack.append(edge) + visit(edge.target) + edgestack.pop() + stackpos[v] = None + else: + if stackpos[v] is not None: # back-edge + result.append(edgestack[stackpos[v]:]) + visit(root) + return result + +def break_cycles(vertices, edges): + """Enumerates a reasonably minimal set of edges that must be removed to + make the graph acyclic.""" + graphs = [(vertices, edges)] + for vertices, edges in graphs: + #print ''.join(vertices), + #print [e.source+e.target for l in edges.values() for e in l] + for component in strong_components(vertices, edges): + #print '-->', ''.join(component) + edge_weights = {} + random_vertex = component.iterkeys().next() + for cycle in all_cycles(random_vertex, vertices, edges): + #print '\tcycle:', [e.source+e.target for e in cycle] + for edge in cycle: + edge_weights[edge] = edge_weights.get(edge, 0) + 1 + if edge_weights: + max_weight = max(edge_weights.values()) + for edge, weight in edge_weights.iteritems(): + if weight == max_weight: + break + # kill this edge + yield edge + new_edges = edges.copy() + new_edges[edge.source] = [e for e in new_edges[edge.source] + if e is not edge] + graphs.append((component, new_edges)) Added: pypy/dist/pypy/tool/math/test/test_graphlib.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/math/test/test_graphlib.py Sun Oct 2 18:45:26 2005 @@ -0,0 +1,54 @@ +import autopath +from pypy.tool.math.graphlib import * + +# XXX transform.py is difficult to test directly + +edges = { + 'A': [Edge('A','B'), Edge('A','C')], + 'B': [Edge('B','D'), Edge('B','E')], + 'C': [Edge('C','F')], + 'D': [Edge('D','D')], + 'E': [Edge('E','A'), Edge('E','C')], + 'F': [], + 'G': [], + } + +def copy_edges(edges): + result = {} + for key, value in edges.items(): + result[key] = value[:] + return result + + +def test_strong_components(): + saved = copy_edges(edges) + result = list(strong_components(edges, edges)) + assert edges == saved + for comp in result: + comp = list(comp) + comp.sort() + result = [''.join(comp) for comp in result] + result.sort() + assert result == ['ABE', 'C', 'D', 'F', 'G'] + +def test_all_cycles(): + saved = copy_edges(edges) + cycles = list(all_cycles('A', edges, edges)) + assert edges == saved + cycles.sort() + expected = [ + [edges['A'][0], edges['B'][1], edges['E'][0]], + [edges['D'][0]], + ] + expected.sort() + assert cycles == expected + +def test_break_cycles(): + saved = copy_edges(edges) + result = list(break_cycles(edges, edges)) + assert edges == saved + assert len(result) == 2 + assert edges['D'][0] in result + assert (edges['A'][0] in result or + edges['B'][1] in result or + edges['E'][0] in result) From arigo at codespeak.net Sun Oct 2 18:53:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 18:53:02 +0200 (CEST) Subject: [pypy-svn] r18085 - in pypy/dist/pypy: annotation tool tool/algo tool/algo/test tool/math translator/backendopt Message-ID: <20051002165302.ABEA027B7B@code1.codespeak.net> Author: arigo Date: Sun Oct 2 18:52:51 2005 New Revision: 18085 Added: pypy/dist/pypy/tool/algo/ - copied from r18084, pypy/dist/pypy/tool/math/ pypy/dist/pypy/tool/algo/test/autopath.py - copied unchanged from r18079, pypy/dist/pypy/tool/test/autopath.py pypy/dist/pypy/tool/algo/test/test_sparsemat.py (contents, props changed) Removed: pypy/dist/pypy/tool/math/ pypy/dist/pypy/tool/unionfind.py pypy/dist/pypy/translator/backendopt/sparsemat.py Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/tool/algo/sparsemat.py pypy/dist/pypy/tool/algo/test/test_graphlib.py pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/malloc.py pypy/dist/pypy/translator/backendopt/ssa.py Log: Introduced a directory 'tool/algo/' for the algorithmic modules. It's a good place to regroup sparsemat, unionfind, and a new graph-manipulation module doing cycle detection (graphs in the general sense, not flow graphs). Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Sun Oct 2 18:52:51 2005 @@ -14,7 +14,7 @@ from pypy.interpreter.argument import Arguments, ArgErr from pypy.rpython.rarithmetic import r_uint from pypy.rpython.objectmodel import r_dict -from pypy.tool.unionfind import UnionFind +from pypy.tool.algo.unionfind import UnionFind from pypy.rpython import lltype from pypy.rpython.memory import lladdress Modified: pypy/dist/pypy/tool/algo/sparsemat.py ============================================================================== --- pypy/dist/pypy/tool/math/sparsemat.py (original) +++ pypy/dist/pypy/tool/algo/sparsemat.py Sun Oct 2 18:52:51 2005 @@ -72,24 +72,3 @@ total -= a * solution[j] solution[i] = total / line[i] return solution - - -def test_sparsemat1(): - import py - M = SparseMatrix(4) - M[0,0] = M[1,1] = M[2,2] = M[3,3] = 1 - M[0,1] = -1.0 - M[1,2] = M[1,3] = -0.5 - M[2,1] = -1.0 - res = M.solve([4, 5, 4, 1]) - assert res == [19, 15, 19, 1] - -def test_sparsemat2(): - import py - M = SparseMatrix(4) - M[0,0] = M[1,1] = M[2,2] = M[3,3] = 1 - M[0,1] = -1.0 - M[1,2] = M[1,3] = -0.5 - M[2,1] = M[2,3] = -0.5 - res = M.solve([6, 3, 6, 0]) - assert res == [14, 8, 10, 0] Modified: pypy/dist/pypy/tool/algo/test/test_graphlib.py ============================================================================== --- pypy/dist/pypy/tool/math/test/test_graphlib.py (original) +++ pypy/dist/pypy/tool/algo/test/test_graphlib.py Sun Oct 2 18:52:51 2005 @@ -1,7 +1,5 @@ import autopath -from pypy.tool.math.graphlib import * - -# XXX transform.py is difficult to test directly +from pypy.tool.algo.graphlib import * edges = { 'A': [Edge('A','B'), Edge('A','C')], Added: pypy/dist/pypy/tool/algo/test/test_sparsemat.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/algo/test/test_sparsemat.py Sun Oct 2 18:52:51 2005 @@ -0,0 +1,23 @@ +import autopath +from pypy.tool.algo.sparsemat import * + + +def test_sparsemat1(): + import py + M = SparseMatrix(4) + M[0,0] = M[1,1] = M[2,2] = M[3,3] = 1 + M[0,1] = -1.0 + M[1,2] = M[1,3] = -0.5 + M[2,1] = -1.0 + res = M.solve([4, 5, 4, 1]) + assert res == [19, 15, 19, 1] + +def test_sparsemat2(): + import py + M = SparseMatrix(4) + M[0,0] = M[1,1] = M[2,2] = M[3,3] = 1 + M[0,1] = -1.0 + M[1,2] = M[1,3] = -0.5 + M[2,1] = M[2,3] = -0.5 + res = M.solve([6, 3, 6, 0]) + assert res == [14, 8, 10, 0] Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Sun Oct 2 18:52:51 2005 @@ -8,7 +8,7 @@ from pypy.annotation import model as annmodel from pypy.rpython.lltype import Bool, typeOf from pypy.rpython import rmodel -from pypy.translator.backendopt import sparsemat +from pypy.tool.algo import sparsemat from pypy.translator.backendopt.support import log BASE_INLINE_THRESHOLD = 32.4 # just enough to inline add__Int_Int() Modified: pypy/dist/pypy/translator/backendopt/malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/malloc.py Sun Oct 2 18:52:51 2005 @@ -1,6 +1,6 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, traverse, checkgraph -from pypy.tool.unionfind import UnionFind +from pypy.tool.algo.unionfind import UnionFind from pypy.rpython import lltype from pypy.translator.simplify import remove_identical_vars from pypy.translator.backendopt.support import log Modified: pypy/dist/pypy/translator/backendopt/ssa.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/ssa.py (original) +++ pypy/dist/pypy/translator/backendopt/ssa.py Sun Oct 2 18:52:51 2005 @@ -1,5 +1,5 @@ from pypy.objspace.flow.model import Variable, mkentrymap, flatten, Block -from pypy.tool.unionfind import UnionFind +from pypy.tool.algo.unionfind import UnionFind class DataFlowFamilyBuilder: """Follow the flow of the data in the graph. Builds a UnionFind grouping From arigo at codespeak.net Sun Oct 2 18:59:06 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 18:59:06 +0200 (CEST) Subject: [pypy-svn] r18086 - pypy/dist/pypy/rpython/test Message-ID: <20051002165906.56CD227B7B@code1.codespeak.net> Author: arigo Date: Sun Oct 2 18:59:03 2005 New Revision: 18086 Modified: pypy/dist/pypy/rpython/test/test_lltype.py Log: fix test. 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 Sun Oct 2 18:59:03 2005 @@ -411,10 +411,12 @@ def test_is_atomic(): U = Struct('inlined', ('z', Signed)) - P = Ptr(RuntimeTypeInfo) + A = Ptr(RuntimeTypeInfo) + P = Ptr(GcStruct('p')) Q = GcStruct('q', ('i', Signed), ('u', U), ('p', P)) O = OpaqueType('O') F = GcForwardReference() + assert A._is_atomic() is True assert P._is_atomic() is False assert Q.i._is_atomic() is True assert Q.u._is_atomic() is True From arigo at codespeak.net Sun Oct 2 19:10:42 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 19:10:42 +0200 (CEST) Subject: [pypy-svn] r18087 - in pypy/dist/pypy: rpython/test translator/c/test Message-ID: <20051002171042.F124427B7B@code1.codespeak.net> Author: arigo Date: Sun Oct 2 19:10:41 2005 New Revision: 18087 Modified: pypy/dist/pypy/rpython/test/test_rfloat.py pypy/dist/pypy/translator/c/test/test_typed.py Log: Minor fixes. Modified: pypy/dist/pypy/rpython/test/test_rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rfloat.py (original) +++ pypy/dist/pypy/rpython/test/test_rfloat.py Sun Oct 2 19:10:41 2005 @@ -53,4 +53,4 @@ return str(f) res = interpret(fn, [1.5]) - assert eval(''.join(res.chars)) == 1.5 + assert float(''.join(res.chars)) == 1.5 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 Sun Oct 2 19:10:41 2005 @@ -295,7 +295,8 @@ def fn(i=float): return str(i) f = self.getcompiled(fn) - assert f(1.0) == fn(1.0) + res = f(1.0) + assert type(res) is str and float(res) == 1.0 def test_uint_arith(self): def fn(i=r_uint): From arigo at codespeak.net Sun Oct 2 19:17:38 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 19:17:38 +0200 (CEST) Subject: [pypy-svn] r18088 - in pypy/dist/pypy/tool/algo: . test Message-ID: <20051002171738.8890227B7B@code1.codespeak.net> Author: arigo Date: Sun Oct 2 19:17:31 2005 New Revision: 18088 Modified: pypy/dist/pypy/tool/algo/ (props changed) pypy/dist/pypy/tool/algo/graphlib.py pypy/dist/pypy/tool/algo/sparsemat.py (props changed) pypy/dist/pypy/tool/algo/test/ (props changed) Log: fixeol + docstrings. Modified: pypy/dist/pypy/tool/algo/graphlib.py ============================================================================== --- pypy/dist/pypy/tool/algo/graphlib.py (original) +++ pypy/dist/pypy/tool/algo/graphlib.py Sun Oct 2 19:17:31 2005 @@ -1,5 +1,9 @@ """ Utilities to manipulate graphs (vertices and edges, not control flow graphs). + +Convention: + 'vertices' is a set of vertices (or a dict with vertices as keys); + 'edges' is a dict mapping vertices to a list of edges with its source. """ class Edge: @@ -23,9 +27,10 @@ def strong_components(vertices, edges): """Enumerates the strongly connected components of a graph. Each one is - a set of vertices where any node can be reached from any other vertex by - following the edges. 'edges' is a dict {vertex: [edges]})""" - + a set of vertices where any vertex can be reached from any other vertex by + following the edges. In a tree, all strongly connected components are + sets of size 1; larger sets are unions of cycles. + """ component_root = {} discovery_time = {} stack = [] From arigo at codespeak.net Sun Oct 2 20:05:55 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 2 Oct 2005 20:05:55 +0200 (CEST) Subject: [pypy-svn] r18089 - in pypy/dist/pypy/tool/algo: . test Message-ID: <20051002180555.ACA8727B76@code1.codespeak.net> Author: arigo Date: Sun Oct 2 20:05:49 2005 New Revision: 18089 Modified: pypy/dist/pypy/tool/algo/graphlib.py pypy/dist/pypy/tool/algo/test/test_graphlib.py Log: Oups, bug and test. Modified: pypy/dist/pypy/tool/algo/graphlib.py ============================================================================== --- pypy/dist/pypy/tool/algo/graphlib.py (original) +++ pypy/dist/pypy/tool/algo/graphlib.py Sun Oct 2 20:05:49 2005 @@ -95,7 +95,7 @@ #print '-->', ''.join(component) edge_weights = {} random_vertex = component.iterkeys().next() - for cycle in all_cycles(random_vertex, vertices, edges): + for cycle in all_cycles(random_vertex, component, edges): #print '\tcycle:', [e.source+e.target for e in cycle] for edge in cycle: edge_weights[edge] = edge_weights.get(edge, 0) + 1 Modified: pypy/dist/pypy/tool/algo/test/test_graphlib.py ============================================================================== --- pypy/dist/pypy/tool/algo/test/test_graphlib.py (original) +++ pypy/dist/pypy/tool/algo/test/test_graphlib.py Sun Oct 2 20:05:49 2005 @@ -50,3 +50,23 @@ assert (edges['A'][0] in result or edges['B'][1] in result or edges['E'][0] in result) + +def test_break_cycles_2(): + # a graph with 20 loops of length 10 each, plus an edge from each loop to + # the next + edges = {} + for i in range(200): + j = i+1 + if j % 10 == 0: + j -= 10 + edges[i] = [Edge(i, j)] + for i in range(20): + edges[i*10].append(Edge(i*10, (i*10+15) % 200)) + # + result = list(break_cycles(edges, edges)) + assert len(result) == 20 + result = [(edge.source, edge.target) for edge in result] + result.sort() + for i in range(20): + assert i*10 <= result[i][0] <= (i+1)*10 + assert i*10 <= result[i][1] <= (i+1)*10 From arigo at codespeak.net Mon Oct 3 01:39:52 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 3 Oct 2005 01:39:52 +0200 (CEST) Subject: [pypy-svn] r18090 - pypy/dist/pypy/tool/algo Message-ID: <20051002233952.20FD027B68@code1.codespeak.net> Author: arigo Date: Mon Oct 3 01:39:52 2005 New Revision: 18090 Modified: pypy/dist/pypy/tool/algo/graphlib.py Log: utility to turn a list of edges into the dict format expected by graphlib. Modified: pypy/dist/pypy/tool/algo/graphlib.py ============================================================================== --- pypy/dist/pypy/tool/algo/graphlib.py (original) +++ pypy/dist/pypy/tool/algo/graphlib.py Mon Oct 3 01:39:52 2005 @@ -4,6 +4,7 @@ Convention: 'vertices' is a set of vertices (or a dict with vertices as keys); 'edges' is a dict mapping vertices to a list of edges with its source. + Note that we can usually use 'edges' as the set of 'vertices' too. """ class Edge: @@ -11,6 +12,13 @@ self.source = source self.target = target +def make_edge_dict(edge_list): + "Put a list of edges in the official dict format." + edges = {} + for edge in edge_list: + edges.setdefault(edge.source, []).append(edge) + return edges + def depth_first_search(root, vertices, edges): seen = {} result = [] From pedronis at codespeak.net Mon Oct 3 02:43:58 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 3 Oct 2005 02:43:58 +0200 (CEST) Subject: [pypy-svn] r18091 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051003004358.D6A1327B69@code1.codespeak.net> Author: pedronis Date: Mon Oct 3 02:43:56 2005 New Revision: 18091 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/g_prerequisite.h Log: avoid requiring the .lib on windows for standalone Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Mon Oct 3 02:43:56 2005 @@ -206,6 +206,7 @@ for key, value in defines.items(): print >> f, '#define %s %s' % (key, value) + print >> f, '#define Py_BUILD_CORE /* for Windows: avoid pulling libs in */' print >> f, '#include "pyconfig.h"' for line in database.gcpolicy.pre_pre_gc_code(): print >> f, line 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 Oct 3 02:43:56 2005 @@ -6,9 +6,6 @@ * 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" From tismer at codespeak.net Mon Oct 3 03:23:39 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 3 Oct 2005 03:23:39 +0200 (CEST) Subject: [pypy-svn] r18092 - in pypy/dist/pypy: objspace/flow translator/backendopt translator/c Message-ID: <20051003012339.62D7527B6C@code1.codespeak.net> Author: tismer Date: Mon Oct 3 03:23:35 2005 New Revision: 18092 Modified: pypy/dist/pypy/objspace/flow/model.py pypy/dist/pypy/translator/backendopt/ssa.py pypy/dist/pypy/translator/c/wrapper.py Log: changed Variable() a little bit to use numbering per distinct name. Had to add a few functions to hide the Variable implementation. I.E. clients should never use v._name or v._nr The effect is a quite measurable reduction of memory requirements during the first passes of translation, because we now never store the variable name strings. Later, in code generation, almost all of this effect vanishes, again. We are still many megabytes smaller, but slightly above 402 MB. I think Variable.name is saved at some place that I did not find, yet. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Mon Oct 3 03:23:35 2005 @@ -94,6 +94,7 @@ from pypy.translator.tool.graphpage import SingleGraphPage SingleGraphPage(self).display() + class Link(object): __slots__ = """args target exitcase llexitcase prevblock @@ -137,6 +138,7 @@ def __repr__(self): return "link from %s to %s" % (str(self.prevblock), str(self.target)) + class Block(object): __slots__ = """isstartblock inputargs operations exitswitch exits exc_handler""".split() @@ -209,40 +211,44 @@ class Variable(object): - __slots__ = ["_name", "concretetype"] + __slots__ = ["_name", "_nr", "concretetype"] - countall = 0 + dummyname = intern('v') + namesdict = {dummyname : 0} def name(self): - name = self._name - if type(name) is int: - name = 'v%d' % name - return name + _name = self._name + _nr = self._nr + if _nr == -1: + # consume numbers lazily + nd = self.namesdict + _nr = self._nr = nd[_name] + nd[_name] = _nr + 1 + return "%s%d" % (_name, _nr) name = property(name) def renamed(self): - return type(self._name) is not int + return self._name is not self.dummyname renamed = property(renamed) def __init__(self, name=None): - self._name = Variable.countall - Variable.countall += 1 + self._name = self.dummyname + self._nr = -1 + # wait with assigning a vxxx number until the name is requested if name is not None: self.rename(name) def __repr__(self): - return '%s' % self.name + return self.name def rename(self, name): - my_number = self._name - if type(my_number) is not int: # don't rename several times + if self._name is not self.dummyname: # don't rename several times return if type(name) is not str: #assert isinstance(name, Variable) -- disabled for speed reasons name = name._name - if type(name) is int: # the other Variable wasn't renamed either + if name is self.dummyname: # the other Variable wasn't renamed either return - name = name[:name.rfind('_')] else: # remove strange characters in the name name = name.translate(PY_IDENTIFIER) @@ -250,25 +256,43 @@ return if name[0] <= '9': # skipped the '0' <= which is always true name = '_' + name - self._name = '%s_%d' % (name, my_number) + name = intern(name + '_') + nd = self.namesdict + nr = nd.get(name, 0) + nd[name] = nr + 1 + self._name = name + self._nr = nr + + def set_name_from(self, v): + # this is for SSI_to_SSA only which should not know about internals + v.name # make sure v's name is finalized + self._name = v._name + self._nr = v._nr + + def set_name(self, name, nr): + # this is for wrapper.py which wants to assign a name explicitly + self._name = intern(name) + self._nr = nr def __reduce_ex__(self, *args): if hasattr(self, 'concretetype'): - return _bv, (self._name, self.concretetype) + return _bv, (self._name, self._nr, self.concretetype) else: - return _bv, (self._name,) + return _bv, (self._name, self._nr) __reduce__ = __reduce_ex__ -def _bv(_name, concretetype=None): +def _bv(_name, _nr, concretetype=None): v = Variable.__new__(Variable, object) v._name = _name + v._nr = _nr if concretetype is not None: v.concretetype = concretetype - if type(_name) is int: - if _name > Variable.countall: - Variable.countall = _name + nd = v.namesdict + if _nr > nd.get(_name, -1): + nd[_name] = _nr + 1 return v + class Constant(Hashable): __slots__ = ["concretetype"] @@ -283,6 +307,7 @@ return Constant, (self.value,) __reduce__ = __reduce_ex__ + class SpaceOperation(object): __slots__ = "opname args result offset".split() @@ -316,6 +341,7 @@ def _sop(opname, result, offset, *args): return SpaceOperation(opname, args, result, offset) + class Atom: def __init__(self, name): self.__name__ = name # make save_global happy Modified: pypy/dist/pypy/translator/backendopt/ssa.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/ssa.py (original) +++ pypy/dist/pypy/translator/backendopt/ssa.py Mon Oct 3 03:23:35 2005 @@ -102,7 +102,7 @@ for v in variable_families.keys(): v1 = variable_families.find_rep(v) if v1 != v: - v._name = v1.name + v.set_name_from(v1) # sanity-check that the same name is never used several times in a block variables_by_name = {} Modified: pypy/dist/pypy/translator/c/wrapper.py ============================================================================== --- pypy/dist/pypy/translator/c/wrapper.py (original) +++ pypy/dist/pypy/translator/c/wrapper.py Mon Oct 3 03:23:35 2005 @@ -59,7 +59,7 @@ vlist.append(Constant(default_value)) v = newops.genop(opname, vlist, resulttype=Ptr(PyObject)) - v._name = 'a%d' % i + v.set_name('a', i) varguments.append(v) if vararg: @@ -69,7 +69,7 @@ Constant(None), ] vararg = newops.genop('getslice', vlist, resulttype=Ptr(PyObject)) - vararg._name = 'vararg' + vararg.set_name('vararg', 0) varguments.append(vararg) else: # "check_no_more_arg(fname, n, vargs)" From tismer at codespeak.net Mon Oct 3 03:53:09 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 3 Oct 2005 03:53:09 +0200 (CEST) Subject: [pypy-svn] r18093 - pypy/dist/pypy/translator/tool Message-ID: <20051003015309.9EABA27B6A@code1.codespeak.net> Author: tismer Date: Mon Oct 3 03:53:04 2005 New Revision: 18093 Modified: pypy/dist/pypy/translator/tool/util.py Log: fixing bugs introduced by non-windows-aware check-ins :-( Modified: pypy/dist/pypy/translator/tool/util.py ============================================================================== --- pypy/dist/pypy/translator/tool/util.py (original) +++ pypy/dist/pypy/translator/tool/util.py Mon Oct 3 03:53:04 2005 @@ -1,5 +1,5 @@ from pypy.tool.udir import udir -import sys +import sys, os def update_usession_dir(stabledir = udir.dirpath('usession')): from py import path From ericvrp at codespeak.net Mon Oct 3 11:41:06 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 3 Oct 2005 11:41:06 +0200 (CEST) Subject: [pypy-svn] r18096 - pypy/dist/pypy/translator/goal Message-ID: <20051003094106.D074627B64@code1.codespeak.net> Author: ericvrp Date: Mon Oct 3 11:41:05 2005 New Revision: 18096 Modified: pypy/dist/pypy/translator/goal/bench-cronjob.py pypy/dist/pypy/translator/goal/bench-unix.py pypy/dist/pypy/translator/goal/driver.py pypy/dist/pypy/translator/goal/run_pypy-llvm.sh Log: fixes for llvm Modified: pypy/dist/pypy/translator/goal/bench-cronjob.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-cronjob.py (original) +++ pypy/dist/pypy/translator/goal/bench-cronjob.py Mon Oct 3 11:41:05 2005 @@ -31,7 +31,7 @@ def compile(backend): os.chdir(homedir + '/projects/pypy-dist/pypy/translator/goal') - os.system('python translate_pypy_new.py targetpypystandalone --backend=%(backend)s --pygame --batch -r 2>&1' % locals()) + os.system('python translate_pypy.py targetpypystandalone --backend=%(backend)s --text --batch 2>&1' % locals()) os.chdir(homedir + '/projects/pypy-dist') try: Modified: pypy/dist/pypy/translator/goal/bench-unix.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-unix.py (original) +++ pypy/dist/pypy/translator/goal/bench-unix.py Mon Oct 3 11:41:05 2005 @@ -46,10 +46,12 @@ txt = run_cmd('%s -c "%s"' % (executable, argstr)) return get_result(txt, RICHARDS_PATTERN) -def get_executables(): +def get_executables(): #sorted by revision number (highest first) exes = [os.path.join('.', name) for name in os.listdir('.') if name.startswith('pypy-')] + exes = [(s.split('-',2)[2], s) for s in exes] exes.sort() exes.reverse() + exes = [s[1] for s in exes] return exes HEADLINE = 'executable richards pystone' @@ -57,14 +59,17 @@ def main(): print HEADLINE + sys.stdout.flush() ref_rich = run_richards() ref_stone = run_pystone() print FMT % ('python %s' % sys.version.split()[0], ref_rich, 1.0, ref_stone, 1.0) + sys.stdout.flush() for exe in get_executables(): exename = os.path.splitext(exe)[0].lstrip('./') rich = run_richards(exe, 1) stone = run_pystone(exe) print FMT % (exename, rich, rich / ref_rich, stone, ref_stone / stone) + sys.stdout.flush() if __name__ == '__main__': main() Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Mon Oct 3 11:41:05 2005 @@ -267,6 +267,13 @@ self.c_entryp = self.llvmgen.create_module(self.llvm_filename, standalone=self.standalone, exe_name = 'pypy-llvm') + if self.standalone: + import shutil + exename = mkexename(self.c_entryp) + newexename = mkexename('./pypy-llvm') + shutil.copy(exename, newexename) + self.c_entryp = newexename + self.log.info("created: %s" % (self.c_entryp,)) # task_compile_llvm = taskdef(task_compile_llvm, ['source_llvm'], Modified: pypy/dist/pypy/translator/goal/run_pypy-llvm.sh ============================================================================== --- pypy/dist/pypy/translator/goal/run_pypy-llvm.sh (original) +++ pypy/dist/pypy/translator/goal/run_pypy-llvm.sh Mon Oct 3 11:41:05 2005 @@ -1,3 +1,3 @@ #!/bin/sh -export RTYPERORDER=order,module-list.pedronis -python translate_pypy.py targetpypystandalone -o -llvm -boehm -text -batch -fork2 $* +#export RTYPERORDER=order,module-list.pedronis +python translate_pypy.py targetpypystandalone --backend=llvm --text --batch $* From ericvrp at codespeak.net Mon Oct 3 13:36:04 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 3 Oct 2005 13:36:04 +0200 (CEST) Subject: [pypy-svn] r18100 - in pypy/dist/pypy/translator/llvm: . module Message-ID: <20051003113604.64AF227B66@code1.codespeak.net> Author: ericvrp Date: Mon Oct 3 13:36:03 2005 New Revision: 18100 Modified: pypy/dist/pypy/translator/llvm/gc.py pypy/dist/pypy/translator/llvm/module/support.py Log: settings GC_all_interior_pointers explicitily. memset malloced data only when is_atomic. Modified: pypy/dist/pypy/translator/llvm/gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/gc.py (original) +++ pypy/dist/pypy/translator/llvm/gc.py Mon Oct 3 13:36:03 2005 @@ -1,3 +1,9 @@ +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("llvm") +log.setconsumer("llvm", ansi_log) + + class GcPolicy: def __init__(self): raise Exception, 'GcPolicy should not be used directly' @@ -21,7 +27,7 @@ from os.path import exists boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') if gcpolicy == 'boehm' and not boehm_on_path: - print 'warning: Boehm GC libary not found in /usr/lib, falling back on no gc' + log.gc.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc') gcpolicy = 'none' if gcpolicy == 'boehm': @@ -55,6 +61,7 @@ return ''' declare ccc sbyte* %GC_malloc(uint) declare ccc sbyte* %GC_malloc_atomic(uint) +%GC_all_interior_pointers = external global int ''' def malloc(self, targetvar, type_, size, is_atomic, word, uword): @@ -62,12 +69,17 @@ self.n_malloced += 1 cnt = '.%d' % self.n_malloced atomic = is_atomic and '_atomic' or '' - return ''' + t = ''' %%malloc.Size%(cnt)s = getelementptr %(type_)s* null, %(uword)s %(s)s %%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to %(uword)s %%malloc.Ptr%(cnt)s = call ccc sbyte* %%GC_malloc%(atomic)s(%(uword)s %%malloc.SizeU%(cnt)s) %(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s* - ''' % locals() +''' % locals() + if is_atomic: + t += ''' +call ccc void %%llvm.memset(sbyte* %%malloc.Ptr%(cnt)s, ubyte 0, uint %%malloc.SizeU%(cnt)s, uint 0) +''' % locals() + return t def pyrex_code(self): return ''' Modified: pypy/dist/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm/module/support.py (original) +++ pypy/dist/pypy/translator/llvm/module/support.py Mon Oct 3 13:36:03 2005 @@ -259,6 +259,7 @@ extfunctions["%main_noargs"] = [(), """ int %main(int %argc, sbyte** %argv) { + store int 0, int* %GC_all_interior_pointers %ret = call fastcc int %pypy_main_noargs() ret int %ret } @@ -267,6 +268,7 @@ extfunctions["%main"] = [(), """ int %main(int %argc, sbyte** %argv) { entry: + store int 0, int* %GC_all_interior_pointers %pypy_argv = call fastcc %structtype.list* %pypy__RPyListOfString_New__Signed(int %argc) br label %no_exit From ericvrp at codespeak.net Mon Oct 3 13:36:33 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 3 Oct 2005 13:36:33 +0200 (CEST) Subject: [pypy-svn] r18101 - in pypy/dist/pypy/translator/llvm: . backendopt Message-ID: <20051003113633.1F88D27B66@code1.codespeak.net> Author: ericvrp Date: Mon Oct 3 13:36:31 2005 New Revision: 18101 Added: pypy/dist/pypy/translator/llvm/backendopt/support.py Modified: pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py pypy/dist/pypy/translator/llvm/build_llvm_module.py pypy/dist/pypy/translator/llvm/exception.py pypy/dist/pypy/translator/llvm/funcnode.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/varsize.py Log: using log instead of print. Modified: pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py ============================================================================== --- pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py (original) +++ pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py Mon Oct 3 13:36:31 2005 @@ -1,8 +1,9 @@ from pypy.objspace.flow.model import Block, flatten, SpaceOperation, Constant, Variable from pypy.rpython.lltype import Struct, GcStruct, Void, Ptr +from pypy.translator.llvm.backendopt.support import log -def merge_mallocs(translator, graph): +def merge_mallocs(translator, graph, ref): """Merge all mallocs of identical in a block into one. Thus all mallocs of atomic data are merged and all mallocs of non-atomic data are also merged into one. This reasoning behind this is @@ -17,19 +18,19 @@ for block in blocks: mallocs = [[], []] for i, op in enumerate(block.operations): - if op.opname == 'malloc' and op.args[0].value._arrayfld: - print 'merge_mallocs: skip varsize', op.args[0] if op.opname != 'malloc' or op.args[0].value._arrayfld: continue is_atomic = op.args[0].value._is_atomic() mallocs[is_atomic].append( (i,op.args[0].value) ) + n_operations_added = 0 for a in range(2): if len(mallocs[a]) >= 2: indices = [m[0] for m in mallocs[a]] gcstructs = [m[1] for m in mallocs[a]] merged_name = 'mergedstructs__' + '_'.join([s._name+str(n) for n, s in enumerate(gcstructs)]) + #add malloc for mergedstruct x = [(gcstruct._name+str(n), gcstruct) for n, gcstruct in enumerate(gcstructs)] mergedstruct= GcStruct(merged_name, *x) c = Constant(mergedstruct, Void) @@ -37,16 +38,15 @@ ptr_merged.concretetype = Ptr(c.value) merged_op = SpaceOperation('malloc', [c], ptr_merged) block.operations.insert(0, merged_op) + n_operations_added += 1 + #replace old mallocs with getsubstruct of mergedstruct for n, i in enumerate(indices): - op = block.operations[i+1] + op = block.operations[i + n_operations_added] field = Constant(x[n][0], Void) - block.operations[i+1] = SpaceOperation('getsubstruct', [ptr_merged, field], op.result) + block.operations[i + n_operations_added] = SpaceOperation('getsubstruct', [ptr_merged, field], op.result) - for m in mallocs[a]: - index, type_ = m - print 'merge_malloc: OLD %d, %s' % (index, type(type_)) - print 'merge_mallocs: NEW %s, %s' % (c, c.concretetype) + log.mergemallocs('%s in function %s' % (c, ref)) n_times_merged += 1 return n_times_merged Modified: pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py ============================================================================== --- pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py (original) +++ pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py Mon Oct 3 13:36:31 2005 @@ -1,7 +1,8 @@ from pypy.objspace.flow.model import Block, Constant, flatten +from pypy.translator.llvm.backendopt.support import log -def remove_exception_mallocs(translator, graph): +def remove_exception_mallocs(translator, graph, ref): """Remove mallocs that occur because an exception is raised. Typically this data is shortlived and occuring often in highlevel languages like Python. So it would be preferable if we would not need @@ -27,7 +28,8 @@ name = str(ops[0].args[0]) if 'Exception' not in name and 'Error' not in name: #XXX better to look at the actual structure continue - print 'remove_exception_malloc: ', name + log.removeexceptionmallocs('%s from function %s' % (name, ref)) ops[0].opname = 'malloc_exception' #XXX refactor later to not use a new operationtype n_removed += 1 + return n_removed Added: pypy/dist/pypy/translator/llvm/backendopt/support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/llvm/backendopt/support.py Mon Oct 3 13:36:31 2005 @@ -0,0 +1,6 @@ +# logging + +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("llvmbackendopt") +py.log.setconsumer("llvmbackendopt", ansi_log) 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 Oct 3 13:36:31 2005 @@ -35,7 +35,6 @@ # flags.insert(flags.index("-inline")+1, "-heap2stack -debug") OPTIMIZATION_SWITCHES = " ".join(flags) -#print OPTIMIZATION_SWITCHES 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/llvm/exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm/exception.py (original) +++ pypy/dist/pypy/translator/llvm/exception.py Mon Oct 3 13:36:31 2005 @@ -46,7 +46,6 @@ decl = node.getdecl() returntype, name = decl.split(' ', 1) noresult = self._noresult(returntype) - #print 'XXX decl=%s -> returntype=%s -> noresult=ret %s' % (decl, returntype, noresult) return noresult def new(exceptionpolicy=None): #factory Modified: pypy/dist/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm/funcnode.py Mon Oct 3 13:36:31 2005 @@ -40,16 +40,10 @@ self.value = value self.ref = self.make_ref('%pypy_', value.graph.name) self.graph = value.graph + self.db.genllvm.exceptionpolicy.transform(self.db.translator, self.graph) - if remove_exception_mallocs(self.db.translator, self.graph): - print ' from function', self.ref - sys.stdout.flush() - #if self.ref not in ('%pypy_ll_raise_OSError__Signed', '%pypy_getitem'): - # self.db.translator.view() - #if merge_mallocs(self.db.translator, self.graph): - # print ' in function', self.ref - # sys.stdout.flush() - # #self.db.translator.view() + remove_exception_mallocs(self.db.translator, self.graph, self.ref) + #merge_mallocs(self.db.translator, self.graph, self.ref) remove_double_links(self.db.translator, self.graph) Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Mon Oct 3 13:36:31 2005 @@ -8,7 +8,6 @@ from pypy.translator.llvm import build_llvm_module from pypy.translator.llvm.database import Database from pypy.translator.llvm.pyxwrapper import write_pyx_wrapper -from pypy.translator.llvm.log import log from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir @@ -24,6 +23,9 @@ from pypy.translator.llvm.exception import ExceptionPolicy from pypy.translator.translator import Translator +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("llvm") +log.setconsumer("llvm", ansi_log) function_count = {} llexterns_header = llexterns_functions = None @@ -48,9 +50,9 @@ if self.debug: if msg: t = (time.time() - self.starttime) - print '\t%s took %02dm%02ds' % (msg, t/60, t%60) + log('\t%s took %02dm%02ds' % (msg, t/60, t%60)) else: - print 'GenLLVM:' + log('GenLLVM:') self.starttime = time.time() def _print_node_stats(self): @@ -85,7 +87,7 @@ stats = [(count, str(typ)) for typ, count in nodecount.iteritems()] stats.sort() for s in stats: - print 'STATS', s + log('STATS %s' % str(s)) def gen_llvm_source(self, func=None): """ @@ -245,7 +247,7 @@ gen = GenLLVM(translator, GcPolicy.new(gcpolicy), ExceptionPolicy.new(exceptionpolicy)) filename = gen.gen_llvm_source() if log_source: - log.genllvm(open(filename).read()) + log(open(filename).read()) return gen.create_module(filename, **kwds) def compile_module(function, annotation, view=False, **kwds): Modified: pypy/dist/pypy/translator/llvm/varsize.py ============================================================================== --- pypy/dist/pypy/translator/llvm/varsize.py (original) +++ pypy/dist/pypy/translator/llvm/varsize.py Mon Oct 3 13:36:31 2005 @@ -26,12 +26,6 @@ codewriter.malloc("%ptr", "sbyte", "%usize", atomic=ARRAY._is_atomic()) 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('%dummy', 'void', '%llvm.memset', ['%ptr', '0', '%usize', '0'], ['sbyte*', 'ubyte', 'uint', 'uint'], cconv='ccc') - else: - codewriter.call('%dummy', 'void', '%llvm.memset', ['%ptr', '0', '%usize', '0'], ['sbyte*', 'ubyte', 'uint', 'uint'], cconv='ccc') - indices_to_arraylength = tuple(indices_to_array) + (("uint", 0),) # the following accesses the length field of the array codewriter.getelementptr("%arraylength", ref + "*", From arigo at codespeak.net Mon Oct 3 14:30:51 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 3 Oct 2005 14:30:51 +0200 (CEST) Subject: [pypy-svn] r18102 - in pypy/dist/pypy/tool/algo: . test Message-ID: <20051003123051.867F327B62@code1.codespeak.net> Author: arigo Date: Mon Oct 3 14:30:47 2005 New Revision: 18102 Modified: pypy/dist/pypy/tool/algo/graphlib.py pypy/dist/pypy/tool/algo/test/test_graphlib.py Log: Added tests until I could isolate the bug in strong_components(). Fix. Modified: pypy/dist/pypy/tool/algo/graphlib.py ============================================================================== --- pypy/dist/pypy/tool/algo/graphlib.py (original) +++ pypy/dist/pypy/tool/algo/graphlib.py Mon Oct 3 14:30:47 2005 @@ -11,12 +11,15 @@ def __init__(self, source, target): self.source = source self.target = target + def __repr__(self): + return '%r -> %r' % (self.source, self.target) def make_edge_dict(edge_list): "Put a list of edges in the official dict format." edges = {} for edge in edge_list: edges.setdefault(edge.source, []).append(edge) + edges.setdefault(edge.target, []) return edges def depth_first_search(root, vertices, edges): @@ -41,13 +44,15 @@ """ component_root = {} discovery_time = {} + remaining = vertices.copy() stack = [] for root in vertices: - if root not in discovery_time: + if root in remaining: - for event, v in depth_first_search(root, vertices, edges): + for event, v in depth_first_search(root, remaining, edges): if event == 'start': + del remaining[v] discovery_time[v] = len(discovery_time) component_root[v] = v stack.append(v) @@ -60,13 +65,13 @@ wroot = component_root[w] if discovery_time[wroot] < discovery_time[vroot]: vroot = wroot - if vroot is v: + if vroot == v: component = {} while True: w = stack.pop() del component_root[w] component[w] = True - if w is v: + if w == v: break yield component else: Modified: pypy/dist/pypy/tool/algo/test/test_graphlib.py ============================================================================== --- pypy/dist/pypy/tool/algo/test/test_graphlib.py (original) +++ pypy/dist/pypy/tool/algo/test/test_graphlib.py Mon Oct 3 14:30:47 2005 @@ -1,72 +1,159 @@ import autopath +import random from pypy.tool.algo.graphlib import * -edges = { - 'A': [Edge('A','B'), Edge('A','C')], - 'B': [Edge('B','D'), Edge('B','E')], - 'C': [Edge('C','F')], - 'D': [Edge('D','D')], - 'E': [Edge('E','A'), Edge('E','C')], - 'F': [], - 'G': [], - } - def copy_edges(edges): result = {} for key, value in edges.items(): result[key] = value[:] return result +# ____________________________________________________________ + +class TestSimple: + edges = { + 'A': [Edge('A','B'), Edge('A','C')], + 'B': [Edge('B','D'), Edge('B','E')], + 'C': [Edge('C','F')], + 'D': [Edge('D','D')], + 'E': [Edge('E','A'), Edge('E','C')], + 'F': [], + 'G': [], + } + + def test_strong_components(self): + edges = self.edges + saved = copy_edges(edges) + result = list(strong_components(edges, edges)) + assert edges == saved + for comp in result: + comp = list(comp) + comp.sort() + result = [''.join(comp) for comp in result] + result.sort() + assert result == ['ABE', 'C', 'D', 'F', 'G'] + + def test_all_cycles(self): + edges = self.edges + saved = copy_edges(edges) + cycles = list(all_cycles('A', edges, edges)) + assert edges == saved + cycles.sort() + expected = [ + [edges['A'][0], edges['B'][1], edges['E'][0]], + [edges['D'][0]], + ] + expected.sort() + assert cycles == expected + + def test_break_cycles(self): + edges = self.edges + saved = copy_edges(edges) + result = list(break_cycles(edges, edges)) + assert edges == saved + assert len(result) == 2 + assert edges['D'][0] in result + assert (edges['A'][0] in result or + edges['B'][1] in result or + edges['E'][0] in result) -def test_strong_components(): - saved = copy_edges(edges) - result = list(strong_components(edges, edges)) - assert edges == saved - for comp in result: - comp = list(comp) - comp.sort() - result = [''.join(comp) for comp in result] - result.sort() - assert result == ['ABE', 'C', 'D', 'F', 'G'] - -def test_all_cycles(): - saved = copy_edges(edges) - cycles = list(all_cycles('A', edges, edges)) - assert edges == saved - cycles.sort() - expected = [ - [edges['A'][0], edges['B'][1], edges['E'][0]], - [edges['D'][0]], - ] - expected.sort() - assert cycles == expected - -def test_break_cycles(): - saved = copy_edges(edges) - result = list(break_cycles(edges, edges)) - assert edges == saved - assert len(result) == 2 - assert edges['D'][0] in result - assert (edges['A'][0] in result or - edges['B'][1] in result or - edges['E'][0] in result) -def test_break_cycles_2(): +class TestLoops: # a graph with 20 loops of length 10 each, plus an edge from each loop to - # the next + # the next, non-cylically edges = {} for i in range(200): j = i+1 if j % 10 == 0: j -= 10 edges[i] = [Edge(i, j)] - for i in range(20): - edges[i*10].append(Edge(i*10, (i*10+15) % 200)) - # - result = list(break_cycles(edges, edges)) - assert len(result) == 20 - result = [(edge.source, edge.target) for edge in result] - result.sort() - for i in range(20): - assert i*10 <= result[i][0] <= (i+1)*10 - assert i*10 <= result[i][1] <= (i+1)*10 + for i in range(19): + edges[i*10].append(Edge(i*10, i*10+15)) + + def test_strong_components(self): + edges = self.edges + result = list(strong_components(edges, edges)) + assert len(result) == 20 + result.sort() + for i in range(20): + comp = list(result[i]) + comp.sort() + assert comp == range(i*10, (i+1)*10) + + def test_break_cycles(self, edges=None): + edges = edges or self.edges + result = list(break_cycles(edges, edges)) + assert len(result) == 20 + result = [(edge.source, edge.target) for edge in result] + result.sort() + for i in range(20): + assert i*10 <= result[i][0] <= (i+1)*10 + assert i*10 <= result[i][1] <= (i+1)*10 + + def test_break_cycles_2(self): + edges = copy_edges(self.edges) + edges[190].append(Edge(190, 5)) + self.test_break_cycles(edges) + + +class TestTree: + edges = make_edge_dict([Edge(i//2, i) for i in range(1, 52)]) + + def test_strong_components(self): + result = list(strong_components(self.edges, self.edges)) + assert len(result) == 52 + vertices = [] + for comp in result: + assert len(comp) == 1 + vertices += comp + vertices.sort() + assert vertices == range(52) + + def test_all_cycles(self): + result = list(all_cycles(0, self.edges, self.edges)) + assert not result + + def test_break_cycles(self): + result = list(break_cycles(self.edges, self.edges)) + assert not result + + +class TestChainAndLoop: + edges = make_edge_dict([Edge(i,i+1) for i in range(100)] + [Edge(100,99)]) + + def test_strong_components(self): + result = list(strong_components(self.edges, self.edges)) + assert len(result) == 100 + vertices = [] + for comp in result: + assert (len(comp) == 1 or + (len(comp) == 2 and 99 in comp and 100 in comp)) + vertices += comp + vertices.sort() + assert vertices == range(101) + + +class TestBugCase: + edges = make_edge_dict([Edge(0,0), Edge(1,0), Edge(1,2), Edge(2,1)]) + + def test_strong_components(self): + result = list(strong_components(self.edges, self.edges)) + assert len(result) == 2 + result.sort() + assert list(result[0]) == [0] + assert list(result[1]) in ([1,2], [2,1]) + + +class TestRandom: + edges = make_edge_dict([Edge(random.randrange(0,100), + random.randrange(0,100)) for i in range(150)]) + + def test_strong_components(self): + result = list(strong_components(self.edges, self.edges)) + vertices = [] + for comp in result: + vertices += comp + vertices.sort() + expected = self.edges.keys() + expected.sort() + assert vertices == expected From arigo at codespeak.net Mon Oct 3 14:50:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 3 Oct 2005 14:50:46 +0200 (CEST) Subject: [pypy-svn] r18103 - pypy/dist/pypy/translator/c Message-ID: <20051003125046.8EAA327B6C@code1.codespeak.net> Author: arigo Date: Mon Oct 3 14:50:43 2005 New Revision: 18103 Modified: pypy/dist/pypy/translator/c/gc.py Log: Boehm seems to be installed in in general, not . It's the case on Debian at least, and Gentoo seems to provide both. Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Mon Oct 3 14:50:43 2005 @@ -359,7 +359,7 @@ #if sys.platform == "linux2": # yield "#define _REENTRANT 1" # yield "#define GC_LINUX_THREADS 1" - yield '#include ' + yield '#include ' yield '#define USING_BOEHM_GC' def gc_startup_code(self): From arigo at codespeak.net Mon Oct 3 16:20:24 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 3 Oct 2005 16:20:24 +0200 (CEST) Subject: [pypy-svn] r18107 - pypy/dist/pypy/objspace/flow Message-ID: <20051003142024.8578B27B72@code1.codespeak.net> Author: arigo Date: Mon Oct 3 16:20:23 2005 New Revision: 18107 Modified: pypy/dist/pypy/objspace/flow/model.py Log: minor fix for pickling Variables. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Mon Oct 3 16:20:23 2005 @@ -288,7 +288,7 @@ if concretetype is not None: v.concretetype = concretetype nd = v.namesdict - if _nr > nd.get(_name, -1): + if _nr >= nd.get(_name, 0): nd[_name] = _nr + 1 return v From arigo at codespeak.net Mon Oct 3 17:56:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 3 Oct 2005 17:56:18 +0200 (CEST) Subject: [pypy-svn] r18110 - pypy/dist/pypy/doc Message-ID: <20051003155618.C7D8927B70@code1.codespeak.net> Author: arigo Date: Mon Oct 3 17:56:13 2005 New Revision: 18110 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: The 'rules' section. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Mon Oct 3 17:56:13 2005 @@ -702,8 +702,8 @@ / / | | \ / NullableStr | | | Int / \ | (lists) | - / Str \ (instances) | (pbcs) - NonNegInt \ \ | | | + / Str \ (instances) | | + NonNegInt \ \ | | (callables) \ Char \ |\ / / Bool \ \ | \ / / \ \ `----- None -----/ @@ -759,10 +759,136 @@ out a number of other annotations that are irrelevant for the basic description of the annotator, and straightforward to handle. The complete list is defined and documented in `pypy/annotation/model.py`_ -and described in more practical terms in `The Annotation Pass`_ in the -reference documentation. +and described in the `annotator reference documentation`_. -.. _`The Annotation Pass`: translation.html#annotator +.. _`annotator reference documentation`: translation.html#annotator + + +Rules +~~~~~ + +In the sequel, we will use the following notations: + +- *A* is the lattice defined above; + +- *V* is the set of variable; + +- *E*, *E'*, *E''*... are equivalence relations on *V*; where + unambiguous, we write *v~v'* to mean that *v* and *v'* are identified + by *E*. + +- *b*, *b'*, *b''*... are maps from *V* to *A*. + +We call *state* a pair *(b,E)*. We say that a state *(b',E')* is more +general than a state *(b,E)* if *E* includes at least all relations of +*E'* and for all variables *v* we have *b'(v) >= b(v)*. There is: + +- a most general state, with *bmax(v) = Top* for all *v* and *Emax* + identifying all variables with each other; + +- a least general state, with *bmin(v) = Bottom* for all *v* and *Emin* + containing no relation (apart from the mandatory *v~v*). + +The goal of the annotator is to find the least general (i.e. most +precise) state that is sound (i.e. correct for the user program). We +will formally introduce the conditions for soundness along the next +sections. The algorithm used is a fixpoint search: we start from the +least general state and consider the conditions repeatedly; if a +condition is not met, we generalize the state incrementally to +accomodate for it. This process continues until all conditions are +satisfied. + +The conditions are presented as a set of rules. A rule is a functional +operation that, when applied, maps a state *(b,E)* to a possibly more +general state *(b',E')* that satisfies the condition represented by the +rule. + +Basically, each operation in the flow graphs of the user program +generates one such rule. The rules are conditional on the annotations +bound to the operation's input argument variables, in a way that mimics +the ad-hoc polymorphic nature of most Python operations. We will not +give all rules in the sequel, but focus on representative examples. +An ``add`` operation generates the following rules:: + + z=add(x,y), b(x)<=Int, b(y)<=Int + ------------------------------------------------------ + b' = b with (z->Int) + + + z=add(x,y), b(x)<=NonNegInt, b(y)<=NonNegInt + ------------------------------------------------------ + b' = b with (z->NonNegInt) + + + z=add(x,y), b(x)<=NullableStr, b(y)<=NullableStr + ------------------------------------------------------ + b' = b with (z->Str) + +The rules are read as follows: for the operation ``z=add(x,y)``, we +consider the bindings of the variables *x* and *y* in the current state +*(b,E)*; if one of the above rules apply, then we produce a new state +*(b',E')* derived from the current state by changing the binding of the +result variable *z*. (Note that for conciseness, we have omitted the +guards in the first rule that prevent it from being applied if the +second rule (which is more precise) applies as well.) + +Also note that we do not generally try to prove the correctness and +safety of the user program, preferring to rely on test coverage for +that. This is apparent in the third rule above, which considers +concatenation of two potentially "nullable" strings, i.e. strings that +the annotator could not prove to be non-None. Instead of reporting an +error, we take it as a hint that the two strings will not actually be +None at run-time and proceed. + +~~~~~~~~~~~~~~~~~~~~~~ + +In the sequel, a lot of rules will be based on the following +``merge_into`` operator. Given two variables *x* and *y*, +``merge_into(x,y)`` modifies the state as follows:: + + merge_into(x,y): + if b(x)=List(v) and b(y)=List(w): + b' = b + E' = E union (v~w) + else: + b' = b with (y -> b(x) \/ b(y)) + E' = E + +where ``\/`` is the union in the lattice *A*. + +The purpose of the equivalence relation *E* is to force two identified +variables to keep the same binding, as defined by the following rule +(which is actually a schema of rules, one each pair of variables +*(x,y)*):: + + (x~y) in E + ---------------------------------------- + merge_into(x,y) + merge_into(y,x) + +Note that in theory, all rules should be tried repeatedly until none of +them generalizes the state any more, at which point we have reached a +fixpoint. In practice, the rules are well suited to simple metarules +that track a smaller set of rules that can possibly apply. Only these +"scheduled" rules are tried. Rules are always applied sequentially. +The metarules are as follows: + +- when an identification *x~y* is added to *E*, then the rule + ``(x~y) in E`` is scheduled to be considered; + +- when a binding *b(x)* is modified, then all rules about operations + that have *x* as an input argument are (re-)scheduled. This includes + the rules ``(x~y) in E`` for each *y* that *E* identifies to *x*. + +These rules and metarules favor a forward propagation: the rule +corresponding to an operation in a flow graph typically modifies the +binding of the operation's result variable which is used in a following +operation in the same block, thus scheduling the following operation's +rule for consideration. The actual process is very similar to -- and +actually implemented as -- abstract interpretation on the flow graphs, +considering each operation in turn in the order they appear in the +block. Effects that are not local to a block trigger a rescheduling of +the whole block instead of single operations. Draft From arigo at codespeak.net Mon Oct 3 18:19:34 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 3 Oct 2005 18:19:34 +0200 (CEST) Subject: [pypy-svn] r18111 - pypy/dist/pypy/doc Message-ID: <20051003161934.4A53627B70@code1.codespeak.net> Author: arigo Date: Mon Oct 3 18:19:31 2005 New Revision: 18111 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Forgot phi operations in the rules. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Mon Oct 3 18:19:31 2005 @@ -856,10 +856,20 @@ where ``\/`` is the union in the lattice *A*. +The above operator is first of all used to propagate bindings of +variables across links between basic block in the control flow graphs. +For every link mapping a variable *x* in the source block to a variable +*y* in the target block, we generate the following rule (``phi`` is not +a normal operation in our `Flow graph model`_; we abuse the notation):: + + y = phi(x) + ---------------------------------------- + merge_into(x,y) + The purpose of the equivalence relation *E* is to force two identified -variables to keep the same binding, as defined by the following rule -(which is actually a schema of rules, one each pair of variables -*(x,y)*):: +variables to keep the same binding. The rationale for this is explained +in the `Mutable objects`_ section below. It is enforced by the +following family of rules (one for each pair *(x,y)*):: (x~y) in E ---------------------------------------- @@ -1020,15 +1030,13 @@ lookup_filter(NonPbcAnnotation, class) = NonPbcAnnotation -XXX model and rules - -XXX constant propagation - Prebuilt constants ~~~~~~~~~~~~~~~~~~ XXX +XXX constant arguments to operations + Mutable objects ~~~~~~~~~~~~~~~ From pedronis at codespeak.net Mon Oct 3 18:23:00 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 3 Oct 2005 18:23:00 +0200 (CEST) Subject: [pypy-svn] r18112 - pypy/dist/pypy/translator/tool Message-ID: <20051003162300.D0A7827B83@code1.codespeak.net> Author: pedronis Date: Mon Oct 3 18:22:55 2005 New Revision: 18112 Modified: pypy/dist/pypy/translator/tool/pdbplus.py Log: fix Modified: pypy/dist/pypy/translator/tool/pdbplus.py ============================================================================== --- pypy/dist/pypy/translator/tool/pdbplus.py (original) +++ pypy/dist/pypy/translator/tool/pdbplus.py Mon Oct 3 18:22:55 2005 @@ -293,7 +293,7 @@ print " ", op print " ", for arg in op.args: - print "%s: %s" (arg, self.translator.getbinding(arg)), + print "%s: %s" % (arg, self.translator.annotator.binding(arg)), print r[func] = True From arigo at codespeak.net Mon Oct 3 19:13:20 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 3 Oct 2005 19:13:20 +0200 (CEST) Subject: [pypy-svn] r18113 - pypy/dist/pypy/doc Message-ID: <20051003171320.58E4127B4B@code1.codespeak.net> Author: arigo Date: Mon Oct 3 19:13:17 2005 New Revision: 18113 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Lists section. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Mon Oct 3 19:13:17 2005 @@ -606,8 +606,8 @@ variables defined earlier in the block, or constants), *z* is the variable into which the result is stored (each operation introduces a new fresh variable as its result), and *z'* is a fresh extra variable -which we will use in particular cases (which we omit from the notation -when it is irrelevant). +called the "auxiliary variable" which we will use in particular cases +(which we omit from the notation when it is irrelevant). Let us assume that we are given a user program, which for the purpose of the model we assume to be fully known in advance. Let us define the set @@ -826,8 +826,9 @@ The rules are read as follows: for the operation ``z=add(x,y)``, we consider the bindings of the variables *x* and *y* in the current state -*(b,E)*; if one of the above rules apply, then we produce a new state -*(b',E')* derived from the current state by changing the binding of the +*(b,E)*; if the bindings satisfy the given conditions, then the rule is +applicable. Applying the rule means producing a new state *(b',E')* +derived from the current state -- here by changing the binding of the result variable *z*. (Note that for conciseness, we have omitted the guards in the first rule that prevent it from being applied if the second rule (which is more precise) applies as well.) @@ -842,6 +843,8 @@ ~~~~~~~~~~~~~~~~~~~~~~ +.. _merge_into: + In the sequel, a lot of rules will be based on the following ``merge_into`` operator. Given two variables *x* and *y*, ``merge_into(x,y)`` modifies the state as follows:: @@ -878,10 +881,10 @@ Note that in theory, all rules should be tried repeatedly until none of them generalizes the state any more, at which point we have reached a -fixpoint. In practice, the rules are well suited to simple metarules -that track a smaller set of rules that can possibly apply. Only these +fixpoint. In practice, the rules are well suited to a simple metarule +that tracks a smaller set of rules that can possibly apply. Only these "scheduled" rules are tried. Rules are always applied sequentially. -The metarules are as follows: +The metarule is as follows: - when an identification *x~y* is added to *E*, then the rule ``(x~y) in E`` is scheduled to be considered; @@ -889,6 +892,8 @@ - when a binding *b(x)* is modified, then all rules about operations that have *x* as an input argument are (re-)scheduled. This includes the rules ``(x~y) in E`` for each *y* that *E* identifies to *x*. + The also includes the cases where *x* is the auxiliary variable + (see `Flow graph model`_). These rules and metarules favor a forward propagation: the rule corresponding to an operation in a flow graph typically modifies the @@ -901,6 +906,93 @@ the whole block instead of single operations. +Mutable objects +~~~~~~~~~~~~~~~ + +Tracking mutable objects is the difficult part of our approach. RPython +contains three types of mutable objects that need special care: lists +(Python's vectors), dictionaries (mappings), and instances of +user-defined classes. The current section focuses on lists; +dictionaries are similar. `Classes and instances`_ will be described in +their own section. + +For lists, we try to derive a homogenous annotation for all items of the +list. In other words, RPython does not support heteregonous lists. The +approach is to consider each list-creation point as building a new type +of list and following the way the list is used to derive the union type +of its items. + +Note that we are not trying to be more precise than finding a single +item type for each list. Flow-sensitive techniques could be potentially +more precise by tracking different possible states for the same list at +different points in the program and in time. But even so, a pure +forward propagation of annotations is not sufficient because of +aliasing: it is possible to take a reference to a list at any point, and +store it somewhere for future access. If a new item is inserted into a +list in a way that generalizes the list's type, all potential aliases +must reflect this change -- this means all references that were "forked" +from the one through which the list is modified. + +To solve this, each list annotation -- ``List(v)`` -- contains an +embedded variable, called the "hidden variable" of the list. It does +not appear directly in the flow graphs of the user program, but +abstractedly stands for "any item of the list". The same annotation +``List(v)`` is propagated forward as with other kinds of annotations. +All aliases of the list end up being annotated as ``List(v)`` with the +same variable *v*. The binding of *v* itself, i.e. ``b(v)``, is updated +to reflect generalization of the list item's type; such an update is +instantly visible to all aliases. Moreover, the update is described as +a change of binding, which means that the metarules will ensure that any +rule based on the binding of this variable will be reconsidered. + +The hidden variable comes from the auxiliary variable syntactically +attached to the operation that produces a list:: + + z=new_list() | z' + ------------------------------------- + b' = b with (z->List(z')) + +Inserting an item into a list is done by merging the new item's +annotation into the list's hidden variable:: + + setitem(x,y,z), b(x)=List(v) + -------------------------------------------- + merge_into(z,v) + +Reading an item out a list requires care to ensure that the rule is +rescheduled if the binding of the hidden variable is generalized. We do +so be identifying the hidden variable with the current operation's +auxiliary variable. The identification ensures that the hidden +variable's binding will eventually propagate to the auxiliary variable, +which -- according to the metarule -- will reschedule the operation's +rule:: + + z=getitem(x,y) | z', b(x)=List(v) + -------------------------------------------- + E' = E union (z'~v) + b' = b with (z->b(z')) + +If you consider the definition of `merge_into`_ again, you will notice +that merging two different lists (for example, two lists that come from +different creation points via different code paths) identifies the two +hidden variables. This effectively identifies the two lists, as if they +had the same origin. It makes the two list annotations aliases for each +other. It allows any storage location to contain lists coming from any +of the two sources indifferently. This process gradually builds a +partition of all lists in the program, where two lists are in the +partition if they are combined in any way. + +As an example of further list operations, here is the addition (which is +the concatenation for lists):: + + z=add(x,y), b(x)=List(v), b(y)=List(w) + -------------------------------------------- + E' = E union (v~w) + b' = b with (z->List(v)) + +As with `merge_into`_, it identifies the two lists. + + Draft ~~~~~ @@ -1037,11 +1129,6 @@ XXX constant arguments to operations -Mutable objects -~~~~~~~~~~~~~~~ - -XXX - Classes and instances ~~~~~~~~~~~~~~~~~~~~~ From pedronis at codespeak.net Mon Oct 3 23:14:02 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 3 Oct 2005 23:14:02 +0200 (CEST) Subject: [pypy-svn] r18117 - in pypy/dist/pypy: annotation translator translator/test Message-ID: <20051003211402.841D727B6C@code1.codespeak.net> Author: pedronis Date: Mon Oct 3 23:13:59 2005 New Revision: 18117 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/translator/annrpython.py pypy/dist/pypy/translator/test/test_annrpython.py Log: (arigo, pedronis) test & fix after chasing for an afternoon: space content Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Mon Oct 3 23:13:59 2005 @@ -201,6 +201,15 @@ getbookkeeper().count("coerce", obj1, obj2) return pair(obj1, obj2).union() # reasonable enough + # approximation of an annotation intersection, the result should be the annotation obj or + # the intersection of obj and improvement + def improve((obj, improvement)): + if not improvement.contains(obj) and obj.contains(improvement): + return improvement + else: + return obj + + # cloning a function with identical code, for the can_only_throw attribute def _clone(f, can_only_throw = None): newfunc = type(f)(f.func_code, f.func_globals, f.func_name, @@ -503,6 +512,25 @@ return SomeObject() return SomeInstance(basedef, can_be_None=ins1.can_be_None or ins2.can_be_None) + def improve((ins1, ins2)): + if ins1.classdef is None: + resdef = ins2.classdef + elif ins2.classdef is None: + resdef = ins1.classdef + else: + basedef = ins1.classdef.commonbase(ins2.classdef) + if basedef is ins1.classdef: + resdef = ins2.classdef + elif basedef is ins2.classdef: + resdef = ins1.classdef + else: + if ins1.can_be_None and ins2.can_be_None: + return SomePBC({None: True}) + else: + return SomeImpossibleValue() + return SomeInstance(resdef, can_be_None=ins1.can_be_None and ins2.can_be_None) + + class __extend__(pairtype(SomeIterator, SomeIterator)): def union((iter1, iter2)): Modified: pypy/dist/pypy/translator/annrpython.py ============================================================================== --- pypy/dist/pypy/translator/annrpython.py (original) +++ pypy/dist/pypy/translator/annrpython.py Mon Oct 3 23:13:59 2005 @@ -582,9 +582,7 @@ cell = self.binding(a) if (link.exitcase, a) in knowntypedata: knownvarvalue = knowntypedata[(link.exitcase, a)] - if not knownvarvalue.contains(cell) and \ - cell.contains(knownvarvalue): # sanity check - cell = knownvarvalue + cell = pair(cell, knownvarvalue).improve() if hasattr(cell,'is_type_of'): renamed_is_type_of = [] 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 Oct 3 23:13:59 2005 @@ -1730,6 +1730,21 @@ a = self.RPythonAnnotator() s = a.build_types(f, []) assert s.knowntype == B + + def test_type_is_no_improvement(self): + class B(object): + pass + class C(B): + pass + class D(B): + pass + def f(x): + if type(x) is C: + return x + raise Exception + a = self.RPythonAnnotator() + s = a.build_types(f, [D]) + assert s == annmodel.SomeImpossibleValue() def g(n): return [0,1,2,n] From cfbolz at codespeak.net Tue Oct 4 02:15:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 02:15:17 +0200 (CEST) Subject: [pypy-svn] r18118 - pypy/dist/pypy/doc Message-ID: <20051004001517.252BF27B3D@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 02:15:11 2005 New Revision: 18118 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: typos Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Tue Oct 4 02:15:11 2005 @@ -91,7 +91,7 @@ Of course, putting more efforts into the toolchain would allow us to support a larger subset of Python. We do not claim that our toolchain -- which we describe in the sequel of this paper -- is particularly advanced. -To make our point, let us assume a given an analysis tool, which supports +To make our point, let us assume as given an analysis tool, which supports a given subset of a language. Then: * Analysing dead source files is equivalent to giving up all dynamism @@ -109,8 +109,9 @@ For example, the source code of the PyPy interpreter, which is itself written in this bounded-dynamism style, makes extensive use of the fact that it is possible to build new classes at any -point in time -- not just during an initialization phase -- as long as this -number of bounded. E.g. `interpreter/gateway.py`_ builds a custom class +point in time -- not just during an initialization phase -- as long as the +number of new classes is bounded. E.g. `interpreter/gateway.py`_ builds a +custom class for each function that some variable can point to. There is a finite number of functions in total, so this can obviously only create a finite number of extra classes. But the precise set of functions that From cfbolz at codespeak.net Tue Oct 4 02:16:34 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 02:16:34 +0200 (CEST) Subject: [pypy-svn] r18119 - pypy/dist/pypy/doc/image Message-ID: <20051004001634.F2E9C27B3D@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 02:16:33 2005 New Revision: 18119 Added: pypy/dist/pypy/doc/image/lattice1.dot pypy/dist/pypy/doc/image/lattice2.dot pypy/dist/pypy/doc/image/lattice3.dot Log: attempts to use graphviz for the lattice graphs in draft-dynamic-language-translation.txt Added: pypy/dist/pypy/doc/image/lattice1.dot ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/image/lattice1.dot Tue Oct 4 02:16:33 2005 @@ -0,0 +1,14 @@ +digraph lattice { + Top -> NullableStr -> Str -> Char -> Bottom; + Top -> Int -> NonNegInt -> Bool -> Bottom; + Top -> "*instances*" -> Bottom; + "*instances*" -> None; + NullableStr -> None; + Top -> "*callables*" -> Bottom; + "*callables*" -> None; + Top -> "*lists*" -> None -> Bottom; + + "*lists*" [shape=box]; + "*instances*" [shape=box]; + "*callables*" [shape=box]; +} Added: pypy/dist/pypy/doc/image/lattice2.dot ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/image/lattice2.dot Tue Oct 4 02:16:33 2005 @@ -0,0 +1,9 @@ +digraph lattice2 { + Top -> "NullableInstance(object)" -> "Instance(object)" -> "Instance(cls1)" -> Bottom; + "NullableInstance(object)" -> "NullableInstance(cls1)" -> None -> Bottom; + "NullableInstance(cls1)" -> "Instance(cls1)"; + + "Instance(object)" -> "Instance(cls2)" -> Bottom; + "NullableInstance(object)" -> "NullableInstance(cls2)" -> "Instance(cls2)"; + "NullableInstance(cls2)" -> None; +} Added: pypy/dist/pypy/doc/image/lattice3.dot ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/image/lattice3.dot Tue Oct 4 02:16:33 2005 @@ -0,0 +1,10 @@ +digraph lattice3 { + Top -> "List(v_1)" -> None; + d1 [label="...", color=white]; + d2 [label="...", color=white]; + d3 [label="...", color=white]; + Top -> d1 -> None; + Top -> d2 -> None; + Top -> d3 -> None; + Top -> "List(v_n)" -> None; +} From ac at codespeak.net Tue Oct 4 09:30:16 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 4 Oct 2005 09:30:16 +0200 (CEST) Subject: [pypy-svn] r18121 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20051004073016.6F58A27B5D@code1.codespeak.net> Author: ac Date: Tue Oct 4 09:30:15 2005 New Revision: 18121 Modified: pypy/dist/pypy/interpreter/astcompiler/misc.py pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Log: Minor cleanup. Modified: pypy/dist/pypy/interpreter/astcompiler/misc.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/misc.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/misc.py Tue Oct 4 09:30:15 2005 @@ -1,4 +1,3 @@ - from pypy.interpreter.astcompiler import ast def flatten(tup): @@ -19,45 +18,6 @@ self.count += 1 return i -class Set: - _annspecialcase_ = "specialize:ctr_location" # polymorphic - - def __init__(self): - self.elts = {} - def __len__(self): - return len(self.elts) - def __contains__(self, elt): - return elt in self.elts - def add(self, elt): - self.elts[elt] = elt - def elements(self): - return self.elts.keys() - def has_elt(self, elt): - return elt in self.elts - def remove(self, elt): - del self.elts[elt] - def copy(self): - c = Set() - c.elts.update(self.elts) - return c - -class Stack: - _annspecialcase_ = "specialize:ctr_location" # polymorphic - - def __init__(self): - self.stack = [] - self.pop = self.stack.pop - def __len__(self): - return len(self.stack) - def push(self, elt): - self.stack.append(elt) - def top(self): - return self.stack[-1] - def __getitem__(self, index): # needed by visitContinue() - return self.stack[index] - def elementAtIndex(self, index): - return self.stack[index] - MANGLE_LEN = 256 # magic constant from compile.c def mangle(name, klass): Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Oct 4 09:30:15 2005 @@ -143,7 +143,7 @@ def __init__(self, space, graph): self.space = space - self.setups = misc.Stack() + self.setups = [] self.last_lineno = -1 self._div_op = "BINARY_DIVIDE" self.genexpr_cont_stack = [] @@ -425,7 +425,7 @@ self.emitop_block('SETUP_LOOP', after) self.nextBlock(loop) - self.setups.push((LOOP, loop)) + self.setups.append((LOOP, loop)) self.set_lineno(node, force=True) node.test.accept( self ) @@ -448,7 +448,7 @@ start = self.newBlock() anchor = self.newBlock() after = self.newBlock() - self.setups.push((LOOP, start)) + self.setups.append((LOOP, start)) self.set_lineno(node) self.emitop_block('SETUP_LOOP', after) @@ -469,15 +469,15 @@ self.nextBlock(after) def visitBreak(self, node): - if not self.setups: + if len(self.setups) == 0: raise SyntaxError( "'break' outside loop", node.lineno) self.set_lineno(node) self.emit('BREAK_LOOP') def visitContinue(self, node): - if not self.setups: + if len(self.setups) == 0: raise SyntaxError( "'continue' not properly in loop", node.lineno) - kind, block = self.setups.top() + kind, block = self.setups[-1] if kind == LOOP: self.set_lineno(node) self.emitop_block('JUMP_ABSOLUTE', block) @@ -485,11 +485,11 @@ elif kind == EXCEPT or kind == TRY_FINALLY: self.set_lineno(node) # find the block that starts the loop - top = len(self.setups.stack) + top = len(self.setups) loop_block = None while top > 0: top = top - 1 - kind, loop_block = self.setups.elementAtIndex(top) + kind, loop_block = self.setups[top] if kind == LOOP: break if kind != LOOP: @@ -741,7 +741,7 @@ self.set_lineno(node) self.emitop_block('SETUP_EXCEPT', handlers) self.nextBlock(body) - self.setups.push((EXCEPT, body)) + self.setups.append((EXCEPT, body)) node.body.accept( self ) self.emit('POP_BLOCK') self.setups.pop() @@ -785,13 +785,13 @@ self.set_lineno(node) self.emitop_block('SETUP_FINALLY', final) self.nextBlock(body) - self.setups.push((TRY_FINALLY, body)) + self.setups.append((TRY_FINALLY, body)) node.body.accept( self ) self.emit('POP_BLOCK') self.setups.pop() self.emitop_obj('LOAD_CONST', self.space.w_None) self.nextBlock(final) - self.setups.push((END_FINALLY, final)) + self.setups.append((END_FINALLY, final)) node.final.accept( self ) self.emit('END_FINALLY') self.setups.pop() @@ -1012,8 +1012,8 @@ self.emit('RETURN_VALUE') def visitYield(self, node): - if self.setups: - kind, block = self.setups.top() + if len(self.setups): + kind, block = self.setups[-1] if kind == TRY_FINALLY: raise SyntaxError("'yield' not allowed in a 'try' block " "with a 'finally' clause", From arigo at codespeak.net Tue Oct 4 11:13:26 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 11:13:26 +0200 (CEST) Subject: [pypy-svn] r18122 - in pypy/dist/pypy: bin translator/tool/pygame Message-ID: <20051004091326.92D7427B57@code1.codespeak.net> Author: arigo Date: Tue Oct 4 11:13:19 2005 New Revision: 18122 Added: pypy/dist/pypy/bin/dotviewer.py (contents, props changed) Modified: pypy/dist/pypy/translator/tool/pygame/cyrvetic.ttf (props changed) pypy/dist/pypy/translator/tool/pygame/graphclient.py Log: Added a unified entry-point script to view dot graphs. The result is a tool that can display .dot files (compiled behind the scene using either a local 'dot' or Codespeak's) as well as "browse" a remote graph server (as run with translate_pypy --graphserve). Added: pypy/dist/pypy/bin/dotviewer.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/bin/dotviewer.py Tue Oct 4 11:13:19 2005 @@ -0,0 +1,32 @@ +#! /usr/bin/env python +""" +Command-line interface for a dot file viewer -- either viewing normal .dot +files or connecting to a graph server like a browser. +""" + +import autopath +import sys, py +from pypy.translator.tool.pygame import graphclient + + +if __name__ == '__main__': + if len(sys.argv) != 2: + print >> sys.stderr, 'Usage: %s filename.dot' % (sys.argv[0],) + print >> sys.stderr, ' %s hostname:port' % (sys.argv[0],) + print >> sys.stderr, ' %s :port' % (sys.argv[0],) + print >> sys.stderr + print >> sys.stderr, ('In the first form, show the graph contained ' + 'in a .dot file.') + print >> sys.stderr, ('In the other forms, connect to a graph server ' + 'like goal/translate_pypy.') + sys.exit(2) + filename = sys.argv[1] + if py.path.local(filename).check(): + graphclient.display_dot_file(filename) + elif filename.count(':') != 1: + print >> sys.stderr, 'No such file:', filename + sys.exit(1) + else: + hostname, port = sys.argv[1].split(':') + port = int(port) + graphclient.display_remote_layout(hostname, port) 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 Tue Oct 4 11:13:19 2005 @@ -41,18 +41,25 @@ str(plainfile), data=request) -class ClientGraphLayout(GraphLayout): - - def __init__(self, connexion, key, dot, links, **ignored): - # generate a temporary .dot file and call dot on it - DOT_FILE.write(dot) +class DotGraphLayout(GraphLayout): + """A graph layout computed by dot from a .dot file. + """ + def __init__(self, dotfilename): try: - dot2plain(DOT_FILE, PLAIN_FILE, use_codespeak=False) + dot2plain(dotfilename, PLAIN_FILE, use_codespeak=False) GraphLayout.__init__(self, PLAIN_FILE) except (py.error.Error, IOError, TypeError, ValueError): # failed, try via codespeak - dot2plain(DOT_FILE, PLAIN_FILE, use_codespeak=True) + dot2plain(dotfilename, PLAIN_FILE, use_codespeak=True) GraphLayout.__init__(self, PLAIN_FILE) + + +class ClientGraphLayout(DotGraphLayout): + + def __init__(self, connexion, key, dot, links, **ignored): + # generate a temporary .dot file and call dot on it + DOT_FILE.write(dot) + DotGraphLayout.__init__(self, DOT_FILE) self.connexion = connexion self.key = key self.links.update(links) @@ -119,6 +126,10 @@ conn.initiate_display(0) display.run() +def display_dot_file(filename): + display = DotGraphLayout(filename).get_display() + display.run() + if __name__ == '__main__': import sys From arigo at codespeak.net Tue Oct 4 11:23:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 11:23:14 +0200 (CEST) Subject: [pypy-svn] r18123 - pypy/dist/pypy/translator/c/test Message-ID: <20051004092314.0033D27B57@code1.codespeak.net> Author: arigo Date: Tue Oct 4 11:23:11 2005 New Revision: 18123 Modified: pypy/dist/pypy/translator/c/test/test_annotated.py Log: In-progress test about recursion detection. Modified: pypy/dist/pypy/translator/c/test/test_annotated.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_annotated.py (original) +++ pypy/dist/pypy/translator/c/test/test_annotated.py Tue Oct 4 11:23:11 2005 @@ -1,4 +1,5 @@ import autopath +import py from pypy.translator.tool.cbuild import skip_missing_compiler from pypy.translator.translator import Translator @@ -165,3 +166,14 @@ fn = self.getcompiled(f) assert fn(-4.5) == 92.125 assert fn(4.5) == 90.125 + + def test_recursion_detection(self): + def f(n=int, accum=int): + if n == 0: + return accum + else: + return f(n-1, accum*n) + fn = self.getcompiled(f) + assert fn(7, 1) == 5040 + py.test.skip("recursion detection: in-progress") + py.test.raises(RuntimeError, fn, -1, 0) From arigo at codespeak.net Tue Oct 4 11:29:56 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 11:29:56 +0200 (CEST) Subject: [pypy-svn] r18124 - in pypy/dist/pypy: annotation translator/test Message-ID: <20051004092956.146E127B57@code1.codespeak.net> Author: arigo Date: Tue Oct 4 11:29:51 2005 New Revision: 18124 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/translator/test/test_annrpython.py Log: Test and fix: the improve() on SomeInstance did not preserve the 'const' attributes. The fix makes sure that the result of improve() is not worse than the original object. Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Tue Oct 4 11:29:51 2005 @@ -528,8 +528,15 @@ return SomePBC({None: True}) else: return SomeImpossibleValue() - return SomeInstance(resdef, can_be_None=ins1.can_be_None and ins2.can_be_None) - + res = SomeInstance(resdef, can_be_None=ins1.can_be_None and ins2.can_be_None) + if ins1.contains(res) and ins2.contains(res): + return res # fine + else: + # this case can occur in the presence of 'const' attributes, + # which we should try to preserve. Fall-back... + thistype = pairtype(SomeInstance, SomeInstance) + return super(thistype, pair(ins1, ins2)).improve() + class __extend__(pairtype(SomeIterator, SomeIterator)): 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 Oct 4 11:29:51 2005 @@ -1745,7 +1745,20 @@ a = self.RPythonAnnotator() s = a.build_types(f, [D]) assert s == annmodel.SomeImpossibleValue() - + + def test_is_constant_instance(self): + class A(object): + pass + prebuilt_instance = A() + def f(x): + if x is prebuilt_instance: + return x + raise Exception + a = self.RPythonAnnotator() + s = a.build_types(f, [A]) + assert s.is_constant() + assert s.const is prebuilt_instance + def g(n): return [0,1,2,n] From arigo at codespeak.net Tue Oct 4 13:00:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 13:00:27 +0200 (CEST) Subject: [pypy-svn] r18127 - pypy/dist/pypy/doc Message-ID: <20051004110027.35A8A27B5C@code1.codespeak.net> Author: arigo Date: Tue Oct 4 13:00:24 2005 New Revision: 18127 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Minor clarifications and a bug fix for the definition of "more general". Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Tue Oct 4 13:00:24 2005 @@ -781,8 +781,8 @@ - *b*, *b'*, *b''*... are maps from *V* to *A*. We call *state* a pair *(b,E)*. We say that a state *(b',E')* is more -general than a state *(b,E)* if *E* includes at least all relations of -*E'* and for all variables *v* we have *b'(v) >= b(v)*. There is: +general than a state *(b,E)* if for all variables *v* we have *b'(v) >= +b(v)* and *E'* includes at least all relations of *E*. There is: - a most general state, with *bmax(v) = Top* for all *v* and *Emax* identifying all variables with each other; @@ -791,25 +791,27 @@ containing no relation (apart from the mandatory *v~v*). The goal of the annotator is to find the least general (i.e. most -precise) state that is sound (i.e. correct for the user program). We -will formally introduce the conditions for soundness along the next -sections. The algorithm used is a fixpoint search: we start from the -least general state and consider the conditions repeatedly; if a -condition is not met, we generalize the state incrementally to -accomodate for it. This process continues until all conditions are -satisfied. +precise) state that is sound (i.e. correct for the user program). The +algorithm used is a fixpoint search: we start from the least general +state and consider the conditions repeatedly; if a condition is not met, +we generalize the state incrementally to accomodate for it. This +process continues until all conditions are satisfied. The conditions are presented as a set of rules. A rule is a functional operation that, when applied, maps a state *(b,E)* to a possibly more general state *(b',E')* that satisfies the condition represented by the -rule. +rule. *Soundness* is formally defined as a state in which all the +conditions are already satisfied, i.e. none of the rules would produce a +strictly more general state. Basically, each operation in the flow graphs of the user program generates one such rule. The rules are conditional on the annotations bound to the operation's input argument variables, in a way that mimics the ad-hoc polymorphic nature of most Python operations. We will not -give all rules in the sequel, but focus on representative examples. -An ``add`` operation generates the following rules:: +give all rules in the sequel, but focus on representative examples. An +``add`` operation generates the following rules (where *x*, *y* and *z* +are replaced by the variables that really appear in each particular +``add`` operation in the flow graphs of the user program):: z=add(x,y), b(x)<=Int, b(y)<=Int ------------------------------------------------------ From arigo at codespeak.net Tue Oct 4 13:17:57 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 13:17:57 +0200 (CEST) Subject: [pypy-svn] r18128 - pypy/dist/pypy/doc Message-ID: <20051004111757.4D5B127B57@code1.codespeak.net> Author: arigo Date: Tue Oct 4 13:17:54 2005 New Revision: 18128 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Fix and explain a bit more the basic rules. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Tue Oct 4 13:17:54 2005 @@ -813,18 +813,18 @@ are replaced by the variables that really appear in each particular ``add`` operation in the flow graphs of the user program):: - z=add(x,y), b(x)<=Int, b(y)<=Int + z=add(x,y), Bool<=b(x)<=Int, Bool<=b(y)<=Int ------------------------------------------------------ b' = b with (z->Int) - z=add(x,y), b(x)<=NonNegInt, b(y)<=NonNegInt - ------------------------------------------------------ + z=add(x,y), Bool<=b(x)<=NonNegInt, Bool<=b(y)<=NonNegInt + ------------------------------------------------------------- b' = b with (z->NonNegInt) - z=add(x,y), b(x)<=NullableStr, b(y)<=NullableStr - ------------------------------------------------------ + z=add(x,y), Char<=b(x)<=NullableStr, Char<=b(y)<=NullableStr + ---------------------------------------------------------------- b' = b with (z->Str) The rules are read as follows: for the operation ``z=add(x,y)``, we @@ -832,9 +832,12 @@ *(b,E)*; if the bindings satisfy the given conditions, then the rule is applicable. Applying the rule means producing a new state *(b',E')* derived from the current state -- here by changing the binding of the -result variable *z*. (Note that for conciseness, we have omitted the -guards in the first rule that prevent it from being applied if the -second rule (which is more precise) applies as well.) +result variable *z*. + +Note that for conciseness, we omitted the guards in the first rule that +prevent it from being applied if the second rule (which is more precise) +applies as well. As none of these rules modify *E*, we also omitted the +``E'=E``. Also note that we do not generally try to prove the correctness and safety of the user program, preferring to rely on test coverage for @@ -1035,50 +1038,6 @@ A: fixed lattice of the above annotation terms - - E(x,y) - ---------------------------------------- - merge_into(x,y) - merge_into(y,x) - - - z=add(x,y), b(x)=List(v), b(y)=List(w) - -------------------------------------------- - E' = E union (v~w) - b' = b with (z->List(v)) - - - z=add(x,y), b(x)<=NullableStr, b(y)<=NullableStr - ------------------------------------------------------ - b' = b with (z->Str) - - - merge_into(x,y), b(x)=List(v), b(y)=List(w) - ------------------------------------------------- - E' = E union (v~w) - - - merge_into(x,y), b(x) and b(y) not both Lists - --------------------------------------------------- - b' = b with (y->b(x)\/b(y)) - - - z=new_list() | z' - ------------------------------------- - b' = b with (z->List(z')) - - - z=getitem(x,y) | z', b(x)=List(v) - -------------------------------------------- - E' = E union (z'~v) - b' = b with (z->b(z')) - - - setitem(x,y,z), b(x)=List(v) - -------------------------------------------- - merge_into(z,v) - - z=getattr(x,attr) | z', b(x)=Inst(A) --------------------------------------------------------------------- E' = E union (A.attr ~ A'.attr) for all A' subclass of A From cfbolz at codespeak.net Tue Oct 4 13:52:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 13:52:16 +0200 (CEST) Subject: [pypy-svn] r18129 - pypy/dist/pypy/doc/tool Message-ID: <20051004115216.8087527B5A@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 13:52:14 2005 New Revision: 18129 Added: pypy/dist/pypy/doc/tool/mydot.py - copied, changed from r18120, user/cfbolz/python/mydot.py Log: little hack that let's you insert latex formulas (using $...$) into dot files From arigo at codespeak.net Tue Oct 4 14:04:09 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 14:04:09 +0200 (CEST) Subject: [pypy-svn] r18130 - pypy/dist/pypy/doc Message-ID: <20051004120409.F1BBE27B5B@code1.codespeak.net> Author: arigo Date: Tue Oct 4 14:04:06 2005 New Revision: 18130 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Typos and slight rewordings. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Tue Oct 4 14:04:06 2005 @@ -888,9 +888,8 @@ Note that in theory, all rules should be tried repeatedly until none of them generalizes the state any more, at which point we have reached a fixpoint. In practice, the rules are well suited to a simple metarule -that tracks a smaller set of rules that can possibly apply. Only these -"scheduled" rules are tried. Rules are always applied sequentially. -The metarule is as follows: +that tracks a small set of rules that can possibly apply. Only these +"scheduled" rules are tried. The metarule is as follows: - when an identification *x~y* is added to *E*, then the rule ``(x~y) in E`` is scheduled to be considered; @@ -898,8 +897,8 @@ - when a binding *b(x)* is modified, then all rules about operations that have *x* as an input argument are (re-)scheduled. This includes the rules ``(x~y) in E`` for each *y* that *E* identifies to *x*. - The also includes the cases where *x* is the auxiliary variable - (see `Flow graph model`_). + This also includes the cases where *x* is the auxiliary variable + of an operation (see `Flow graph model`_). These rules and metarules favor a forward propagation: the rule corresponding to an operation in a flow graph typically modifies the @@ -931,7 +930,7 @@ Note that we are not trying to be more precise than finding a single item type for each list. Flow-sensitive techniques could be potentially more precise by tracking different possible states for the same list at -different points in the program and in time. But even so, a pure +different points in the program and in time. But in any case, a pure forward propagation of annotations is not sufficient because of aliasing: it is possible to take a reference to a list at any point, and store it somewhere for future access. If a new item is inserted into a @@ -942,14 +941,15 @@ To solve this, each list annotation -- ``List(v)`` -- contains an embedded variable, called the "hidden variable" of the list. It does not appear directly in the flow graphs of the user program, but -abstractedly stands for "any item of the list". The same annotation -``List(v)`` is propagated forward as with other kinds of annotations. -All aliases of the list end up being annotated as ``List(v)`` with the -same variable *v*. The binding of *v* itself, i.e. ``b(v)``, is updated -to reflect generalization of the list item's type; such an update is -instantly visible to all aliases. Moreover, the update is described as -a change of binding, which means that the metarules will ensure that any -rule based on the binding of this variable will be reconsidered. +abstractedly stands for "any item of the list". The annotation +``List(v)`` is propagated forward as with other kinds of annotations, so +that all aliases of the list end up being annotated as ``List(v)`` with +the same variable *v*. The binding of *v* itself, i.e. ``b(v)``, is +updated to reflect generalization of the list item's type; such an +update is instantly visible to all aliases. Moreover, the update is +described as a change of binding, which means that the metarules will +ensure that any rule based on the binding of this variable will be +reconsidered. The hidden variable comes from the auxiliary variable syntactically attached to the operation that produces a list:: @@ -959,7 +959,8 @@ b' = b with (z->List(z')) Inserting an item into a list is done by merging the new item's -annotation into the list's hidden variable:: +annotation into the list's hidden variable (*y* is the index in the list +*x* and *z* is the new item):: setitem(x,y,z), b(x)=List(v) -------------------------------------------- @@ -983,8 +984,8 @@ different creation points via different code paths) identifies the two hidden variables. This effectively identifies the two lists, as if they had the same origin. It makes the two list annotations aliases for each -other. It allows any storage location to contain lists coming from any -of the two sources indifferently. This process gradually builds a +other, allowing any storage location to contain lists coming from any of +the two sources indifferently. This process gradually builds a partition of all lists in the program, where two lists are in the partition if they are combined in any way. @@ -1129,7 +1130,7 @@ In the extended lattice used in practice it is more difficult to compute an upper bound. Such a bound exists -- some considerations can even show that a finite subset of the extended lattice suffices -- but it -does not reflect any partical complexity considerations. It is simpler +does not reflect any practical complexity considerations. It is simpler to prove that there is no infinite ascending chain, which is enough to guarantee termination. From arigo at codespeak.net Tue Oct 4 14:12:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 14:12:30 +0200 (CEST) Subject: [pypy-svn] r18131 - in pypy/dist/pypy/rpython: . test Message-ID: <20051004121230.E37BF27B5B@code1.codespeak.net> Author: arigo Date: Tue Oct 4 14:12:26 2005 New Revision: 18131 Modified: pypy/dist/pypy/rpython/rstr.py pypy/dist/pypy/rpython/test/test_rstr.py Log: test and fix for str.lower() -- using 96 as the (wrong) ord of 'Z'. Rewrote the implementation in a way that prevents this kind of error. Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Tue Oct 4 14:12:26 2005 @@ -831,12 +831,10 @@ i = 0 result = malloc(STR, s_len) while i < s_len: - ochar = ord(s_chars[i]) - if ochar >= 97 and ochar <= 122: - upperchar = ochar - 32 - else: - upperchar = ochar - result.chars[i] = chr(upperchar) + ch = s_chars[i] + if 'a' <= ch <= 'z': + ch = chr(ord(ch) - 32) + result.chars[i] = ch i += 1 return result @@ -848,12 +846,10 @@ i = 0 result = malloc(STR, s_len) while i < s_len: - ochar = ord(s_chars[i]) - if ochar >= 65 and ochar <= 96: - lowerchar = ochar + 32 - else: - lowerchar = ochar - result.chars[i] = chr(lowerchar) + ch = s_chars[i] + if 'A' <= ch <= 'Z': + ch = chr(ord(ch) + 32) + result.chars[i] = ch i += 1 return result 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 Oct 4 14:12:26 2005 @@ -263,18 +263,20 @@ assert res == fn(ch) def test_upper(): + strings = ['', ' ', 'upper', 'UpPeR', ',uppEr,'] + for i in range(256): strings.append(chr(i)) def fn(i): - strings = ['', ' ', 'upper', 'UpPeR', ',uppEr,'] return strings[i].upper() - for i in range(5): + for i in range(len(strings)): res = interpret(fn, [i]) assert ''.join(res.chars) == fn(i) def test_lower(): + strings = ['', ' ', 'lower', 'LoWeR', ',lowEr,'] + for i in range(256): strings.append(chr(i)) def fn(i): - strings = ['', ' ', 'lower', 'LoWeR', ',lowEr,'] return strings[i].lower() - for i in range(5): + for i in range(len(strings)): res = interpret(fn, [i]) assert ''.join(res.chars) == fn(i) From tismer at codespeak.net Tue Oct 4 14:33:02 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 4 Oct 2005 14:33:02 +0200 (CEST) Subject: [pypy-svn] r18132 - in pypy/dist/pypy/translator: . test Message-ID: <20051004123302.8A5CA27B5A@code1.codespeak.net> Author: tismer Date: Tue Oct 4 14:33:01 2005 New Revision: 18132 Added: pypy/dist/pypy/translator/test/test_uniquename.py (contents, props changed) Modified: pypy/dist/pypy/translator/gensupp.py Log: changed uniquename to really ensure unique names. an extra check is done whenever we change the name. modified it so that digits never get attached to digits. Modified: pypy/dist/pypy/translator/gensupp.py ============================================================================== --- pypy/dist/pypy/translator/gensupp.py (original) +++ pypy/dist/pypy/translator/gensupp.py Tue Oct 4 14:33:01 2005 @@ -100,30 +100,28 @@ raise NameError, "%s has already been seen!" self.seennames[name] = 1 + def _ensure_unique(self, basename): + n = self.seennames.get(basename, 0) + self.seennames[basename] = n+1 + if n: + return self._ensure_unique('%s_%d' % (basename, n)) + return basename + def uniquename(self, basename, with_number=None, bare=False, lenmax=50): basename = basename[:lenmax].translate(C_IDENTIFIER) n = self.seennames.get(basename, 0) self.seennames[basename] = n+1 if with_number is None: with_number = basename in ('v', 'w_') - if with_number: - if n == 0: - 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), bare=bare, - lenmax=sys.maxint) - if n == 0: - if bare: - return basename, self.global_prefix + basename - else: - return self.global_prefix + basename + fmt = '%s_%d' + if with_number and not basename[-1].isdigit(): + fmt = '%s%d' + if n != 0 or with_number: + basename = self._ensure_unique(fmt % (basename, n)) + if bare: + return basename, self.global_prefix + basename else: - return self.uniquename('%s_%d' % (basename, n), bare=bare, - lenmax=sys.maxint) + return self.global_prefix + basename def localScope(self, parent=None): ret = _LocalScope(self, parent) Added: pypy/dist/pypy/translator/test/test_uniquename.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/test/test_uniquename.py Tue Oct 4 14:33:01 2005 @@ -0,0 +1,15 @@ +from pypy.translator.gensupp import NameManager + +def test_unique(): + m = NameManager() + sn = m.seennames + check = [ + m.uniquename('something0'), + m.uniquename('something', with_number=True), + m.uniquename('something', with_number=True), + m.uniquename('something2', with_number=True), + m.uniquename('something1'), + m.uniquename('something1_1'), + ] + assert check == ['something0', 'something0_1', 'something1', + 'something2_0', 'something1_1', 'something1_1_1'] From bea at codespeak.net Tue Oct 4 15:27:23 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Tue, 4 Oct 2005 15:27:23 +0200 (CEST) Subject: [pypy-svn] r18134 - pypy/extradoc/sprintinfo Message-ID: <20051004132723.602B927B57@code1.codespeak.net> Author: bea Date: Tue Oct 4 15:27:21 2005 New Revision: 18134 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: more sprinters Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Tue Oct 4 15:27:21 2005 @@ -26,7 +26,7 @@ Anders Lehmann 09/10 - 14/10 Hotel Porte de Versailles Boris Feigin 09/10 - 16/10 ?/looking for flatmates Amaury Forgeot d'Arc10/10 - 16/10 Private -=================== ============== ===================== +Andrew Thompson 09/10 - 17/10 Citea Vanves Portes de Versailles People on the following list are likely to come and were present at the previous sprints: From pedronis at codespeak.net Tue Oct 4 15:39:08 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 4 Oct 2005 15:39:08 +0200 (CEST) Subject: [pypy-svn] r18135 - pypy/extradoc/sprintinfo Message-ID: <20051004133908.7032627B56@code1.codespeak.net> Author: pedronis Date: Tue Oct 4 15:39:07 2005 New Revision: 18135 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: arre's and my dates Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Tue Oct 4 15:39:07 2005 @@ -17,7 +17,8 @@ Laura Creighton ? ? Beatrice Duering 9/10 - 17/10 flat Armin Rigo ? ? -Samuele Pedroni ? ? +Samuele Pedroni 9/10 - 17/10 Hotel +Anders Chrigstroem 9/10 - 17/10 Hotel Holger Krekel 6th-17th Oct flat Lene Wagner 12th-13th Oct flat Michael Hudson ? ? @@ -37,6 +38,5 @@ Niklaus Haldimann ? ? Eric van Riet Paap ? ? Richard Emslie ? ? -Anders Chrigstroem ? ? Christian Tismer ? ? =================== ============== ===================== From tismer at codespeak.net Tue Oct 4 16:11:50 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 4 Oct 2005 16:11:50 +0200 (CEST) Subject: [pypy-svn] r18136 - pypy/dist/pypy/objspace/flow Message-ID: <20051004141150.78AD327B57@code1.codespeak.net> Author: tismer Date: Tue Oct 4 16:11:49 2005 New Revision: 18136 Modified: pypy/dist/pypy/objspace/flow/model.py Log: simplified Variable a bit, again. Not using intern, but storing a (name, nr) tuple, instead. Numbers are now bound lazily in all cases. This creates slightly more sorted output. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Tue Oct 4 16:11:49 2005 @@ -213,8 +213,8 @@ class Variable(object): __slots__ = ["_name", "_nr", "concretetype"] - dummyname = intern('v') - namesdict = {dummyname : 0} + dummyname = 'v' + namesdict = {dummyname : (dummyname, 0)} def name(self): _name = self._name @@ -222,8 +222,8 @@ if _nr == -1: # consume numbers lazily nd = self.namesdict - _nr = self._nr = nd[_name] - nd[_name] = _nr + 1 + _nr = self._nr = nd[_name][1] + nd[_name] = (_name, _nr + 1) return "%s%d" % (_name, _nr) name = property(name) @@ -234,7 +234,7 @@ def __init__(self, name=None): self._name = self.dummyname self._nr = -1 - # wait with assigning a vxxx number until the name is requested + # numbers are bound lazily, when the name is requested if name is not None: self.rename(name) @@ -251,17 +251,11 @@ return else: # remove strange characters in the name - name = name.translate(PY_IDENTIFIER) - if not name: - return + name = name.translate(PY_IDENTIFIER) + '_' if name[0] <= '9': # skipped the '0' <= which is always true name = '_' + name - name = intern(name + '_') - nd = self.namesdict - nr = nd.get(name, 0) - nd[name] = nr + 1 + name = self.namesdict.setdefault(name, (name, 0))[0] self._name = name - self._nr = nr def set_name_from(self, v): # this is for SSI_to_SSA only which should not know about internals From jacob at codespeak.net Tue Oct 4 16:36:44 2005 From: jacob at codespeak.net (jacob at codespeak.net) Date: Tue, 4 Oct 2005 16:36:44 +0200 (CEST) Subject: [pypy-svn] r18137 - pypy/extradoc/sprintinfo Message-ID: <20051004143644.AA0CD27B58@code1.codespeak.net> Author: jacob Date: Tue Oct 4 16:36:43 2005 New Revision: 18137 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: Dates and accomodation for Strakt & Laura Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Tue Oct 4 16:36:43 2005 @@ -13,12 +13,12 @@ =================== ============== ===================== Ludovic Aubry 10/10 - 16/10 Private Adrien Di Mascio 10/10 - 16/10 Private -Jacob Hallen ? ? -Laura Creighton ? ? +Jacob Hallen 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) +Laura Creighton 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Beatrice Duering 9/10 - 17/10 flat Armin Rigo ? ? -Samuele Pedroni 9/10 - 17/10 Hotel -Anders Chrigstroem 9/10 - 17/10 Hotel +Samuele Pedroni 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) +Anders Chrigstroem 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Holger Krekel 6th-17th Oct flat Lene Wagner 12th-13th Oct flat Michael Hudson ? ? From cfbolz at codespeak.net Tue Oct 4 17:18:36 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 17:18:36 +0200 (CEST) Subject: [pypy-svn] r18140 - pypy/dist/pypy/doc/tool Message-ID: <20051004151836.C1F9A27B57@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 17:18:35 2005 New Revision: 18140 Modified: pypy/dist/pypy/doc/tool/mydot.py Log: for png export, first convert the file to eps, to reduce the white space. Modified: pypy/dist/pypy/doc/tool/mydot.py ============================================================================== --- pypy/dist/pypy/doc/tool/mydot.py (original) +++ pypy/dist/pypy/doc/tool/mydot.py Tue Oct 4 17:18:35 2005 @@ -60,6 +60,15 @@ oldpath.chdir() return output +def ps2eps(ps): + try: + py.process.cmdexec("ps2eps -l -f %s" % ps) + except: + try: + py.process.cmdexec("ps2epsi %s %s" % (psfile, eps)) + except: + raise OSError("neither ps2eps nor ps2epsi found") + if __name__ == '__main__': import optparse parser = optparse.OptionParser() @@ -72,12 +81,13 @@ if options.format == "ps": print psfile.read() elif options.format == "eps": - py.process.cmdexec("ps2eps -l -f %s" % psfile) + ps2eps(psfile) eps = psfile.new(ext="eps") print eps.read() elif options.format == "png": - py.process.cmdexec("convert %s %s" % - (psfile, psfile.new(ext="png"))) + ps2eps(psfile) + eps = psfile.new(ext="eps") + py.process.cmdexec("convert %s %s" % (eps, psfile.new(ext="png"))) png = psfile.new(ext="png") print png.read() From pedronis at codespeak.net Tue Oct 4 18:46:32 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 4 Oct 2005 18:46:32 +0200 (CEST) Subject: [pypy-svn] r18156 - pypy/tag/pypy-0.6.1 Message-ID: <20051004164632.1D95627B56@code1.codespeak.net> Author: pedronis Date: Tue Oct 4 18:46:30 2005 New Revision: 18156 Added: pypy/tag/pypy-0.6.1/ - copied from r18155, pypy/branch/0.6.x/ Log: making a tag for 0.6.1 From cfbolz at codespeak.net Tue Oct 4 18:52:42 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 18:52:42 +0200 (CEST) Subject: [pypy-svn] r18157 - pypy/dist/pypy/doc/tool Message-ID: <20051004165242.13D0027B56@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 18:52:40 2005 New Revision: 18157 Modified: pypy/dist/pypy/doc/tool/mydot.py Log: if conversion to eps is not possible, still use conversion on ps directly Modified: pypy/dist/pypy/doc/tool/mydot.py ============================================================================== --- pypy/dist/pypy/doc/tool/mydot.py (original) +++ pypy/dist/pypy/doc/tool/mydot.py Tue Oct 4 18:52:40 2005 @@ -85,10 +85,14 @@ eps = psfile.new(ext="eps") print eps.read() elif options.format == "png": - ps2eps(psfile) - eps = psfile.new(ext="eps") - py.process.cmdexec("convert %s %s" % (eps, psfile.new(ext="png"))) png = psfile.new(ext="png") + eps = psfile.new(ext="eps") + try: + ps2eps(psfile) + except: + #ok, no eps converter found + py.process.cmdexec("convert %s %s" % (psfile, png)) + else: + py.process.cmdexec("convert %s %s" % (eps, png)) print png.read() - From ac at codespeak.net Tue Oct 4 19:31:41 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 4 Oct 2005 19:31:41 +0200 (CEST) Subject: [pypy-svn] r18159 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20051004173141.90B8E27B57@code1.codespeak.net> Author: ac Date: Tue Oct 4 19:31:41 2005 New Revision: 18159 Modified: pypy/dist/pypy/interpreter/pyparser/error.py Log: Get correct default. Modified: pypy/dist/pypy/interpreter/pyparser/error.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/error.py (original) +++ pypy/dist/pypy/interpreter/pyparser/error.py Tue Oct 4 19:31:41 2005 @@ -3,7 +3,7 @@ class SyntaxError(Exception): """Base class for exceptions raised by the parser.""" - def __init__(self, msg, lineno=0, offset=0, text="", filename=""): + def __init__(self, msg, lineno=0, offset=0, text=None, filename=None): self.msg = msg self.lineno = lineno self.offset = offset From ac at codespeak.net Tue Oct 4 19:32:26 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 4 Oct 2005 19:32:26 +0200 (CEST) Subject: [pypy-svn] r18160 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20051004173226.6984727B57@code1.codespeak.net> Author: ac Date: Tue Oct 4 19:32:25 2005 New Revision: 18160 Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/astcompiler/symbols.py Log: Refactor finding incorrect returns Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Tue Oct 4 19:32:25 2005 @@ -1006,8 +1006,6 @@ if node.value is None: self.emitop_obj('LOAD_CONST', self.space.w_None) else: - if self.scope.generator: - raise SyntaxError("'return' with argument inside generator", node.lineno) node.value.accept( self ) self.emit('RETURN_VALUE') Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Tue Oct 4 19:32:25 2005 @@ -31,6 +31,7 @@ # i.e. if it is nested within another function. self.nested = 0 self.generator = False + self.firstReturnWithArgument = None self.klass = None if klass is not None: for i in range(len(klass)): @@ -232,7 +233,7 @@ self.klass = None self.scope_stack = [] self.assign_stack = [ False ] - + def cur_assignment(self): return self.assign_stack[-1] @@ -303,7 +304,6 @@ self.handle_free_vars(scope, parent) def visitGenExprInner(self, node ): - #scope = self.cur_scope() for genfor in node.quals: genfor.accept( self ) @@ -483,23 +483,27 @@ # prune if statements if tests are false - def visitIf(self, node ): - for test, body in node.tests: - if isinstance(test, ast.Const): - if not self.space.is_true(test.value): - continue - test.accept( self ) - body.accept( self ) - if node.else_: - node.else_.accept( self ) - # a yield statement signals a generator def visitYield(self, node ): scope = self.cur_scope() scope.generator = True + if scope.firstReturnWithArgument is not None: + raise SyntaxError("'return' with argument inside generator", + scope.firstReturnWithArgument.lineno) + node.value.accept( self ) - + + def visitReturn(self, node): + scope = self.cur_scope() + if node.value is not None: + if scope.generator: + raise SyntaxError("'return' with argument inside generator", + node.lineno) + if scope.firstReturnWithArgument is None: + scope.firstReturnWithArgument = node + node.value.accept(self) + def sort(l): l = l[:] l.sort() From ac at codespeak.net Tue Oct 4 20:10:36 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 4 Oct 2005 20:10:36 +0200 (CEST) Subject: [pypy-svn] r18161 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20051004181036.6E76527B57@code1.codespeak.net> Author: ac Date: Tue Oct 4 20:10:36 2005 New Revision: 18161 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Log: Give tokens correct lineno info. Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Tue Oct 4 20:10:36 2005 @@ -1615,10 +1615,10 @@ # print "\t", self.rule_stack def push_tok(self, name, value, src ): - self.push( TokenObject( name, value, src._lineno ) ) + self.push( TokenObject( name, value, src._token_lnum ) ) def push_rule(self, name, count, src ): - self.push( RuleObject( name, count, src._lineno ) ) + self.push( RuleObject( name, count, src._token_lnum ) ) def alternative( self, rule, source ): # Do nothing, keep rule on top of the stack Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Tue Oct 4 20:10:36 2005 @@ -296,6 +296,7 @@ self.token_stack = tokens self._current_line = '' # the current line (as a string) self._lineno = -1 + self._token_lnum = 0 self._offset = 0 self.stack_pos = 0 @@ -307,6 +308,7 @@ self.stack_pos += 1 self._current_line = line self._lineno = max(self._lineno, lnum) + self._token_lnum = lnum self._offset = pos return tok From tismer at codespeak.net Tue Oct 4 20:42:23 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 4 Oct 2005 20:42:23 +0200 (CEST) Subject: [pypy-svn] r18162 - pypy/extradoc/sprintinfo Message-ID: <20051004184223.9754E27B57@code1.codespeak.net> Author: tismer Date: Tue Oct 4 20:42:22 2005 New Revision: 18162 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: update for most probable hotel info Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Tue Oct 4 20:42:22 2005 @@ -8,26 +8,29 @@ column are known to be coming but there are no details available yet from them. -=================== ============== ===================== - Name Arrive/Depart Accomodation -=================== ============== ===================== -Ludovic Aubry 10/10 - 16/10 Private -Adrien Di Mascio 10/10 - 16/10 Private -Jacob Hallen 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) -Laura Creighton 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) -Beatrice Duering 9/10 - 17/10 flat -Armin Rigo ? ? -Samuele Pedroni 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) -Anders Chrigstroem 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) -Holger Krekel 6th-17th Oct flat -Lene Wagner 12th-13th Oct flat -Michael Hudson ? ? -Carl Friedrich Bolz 7/10? - 16/10 flat? -Bert Freudenberg 09/10 - 17/10 ? -Anders Lehmann 09/10 - 14/10 Hotel Porte de Versailles -Boris Feigin 09/10 - 16/10 ?/looking for flatmates -Amaury Forgeot d'Arc10/10 - 16/10 Private -Andrew Thompson 09/10 - 17/10 Citea Vanves Portes de Versailles +==================== ============== ===================== + Name Arrive/Depart Accomodation +==================== ============== ===================== +Ludovic Aubry 10/10 - 16/10 Private +Adrien Di Mascio 10/10 - 16/10 Private +Jacob Hallen 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) +Laura Creighton 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) +Beatrice Duering 9/10 - 17/10 flat +Armin Rigo ? ? +Samuele Pedroni 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) +Anders Chrigstroem 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) +Holger Krekel 6th-17th Oct flat +Lene Wagner 12th-13th Oct flat +Michael Hudson ? ? +Carl Friedrich Bolz 7/10? - 16/10 flat? +Bert Freudenberg 09/10 - 17/10 ? +Anders Lehmann 09/10 - 14/10 Hotel Porte de Versailles +Boris Feigin 09/10 - 16/10 ?/looking for flatmates +Amaury Forgeot d'Arc 10/10 - 16/10 Private +Andrew Thompson 09/10 - 17/10 Citea Vanves Portes de Versailles +Christian Tismer 09/10 - 16/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) + (most probably, have to call tomorrow morning, just one room left) +==================== ============== ===================== People on the following list are likely to come and were present at the previous sprints: From ac at codespeak.net Tue Oct 4 20:45:02 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 4 Oct 2005 20:45:02 +0200 (CEST) Subject: [pypy-svn] r18163 - in pypy/dist/pypy: interpreter tool translator/goal Message-ID: <20051004184502.3F6A027B57@code1.codespeak.net> Author: ac Date: Tue Oct 4 20:45:01 2005 New Revision: 18163 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/tool/option.py pypy/dist/pypy/translator/goal/targetpypymain.py pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: Switch to using astcompiler as default compiler. Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Tue Oct 4 20:45:01 2005 @@ -113,7 +113,7 @@ nofaking=False, uselibfile=False, parser="pypy", - compiler="stable", + compiler="ast", translating=False, geninterp=True, **kw Modified: pypy/dist/pypy/tool/option.py ============================================================================== --- pypy/dist/pypy/tool/option.py (original) +++ pypy/dist/pypy/tool/option.py Tue Oct 4 20:45:01 2005 @@ -12,7 +12,7 @@ uselibfile = 0 nofaking = 0 parser = "pypy" # "cpython" / "pypy" - compiler = "stable" + compiler = "ast" # "stable" uses interpreter/pyparser & interpreter/stablecompiler # "_stable" uses intepreter/pyparser & lib/_stablecompiler # "ast" uses interpreter/pyparser & interpreter/astcompiler.py Modified: pypy/dist/pypy/translator/goal/targetpypymain.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypymain.py (original) +++ pypy/dist/pypy/translator/goal/targetpypymain.py Tue Oct 4 20:45:01 2005 @@ -59,7 +59,7 @@ # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None space = StdObjSpace(nofaking=True, - compiler="_stable", # lib/_stablecompiler + compiler="ast", # interpreter/astcompiler 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 Tue Oct 4 20:45:01 2005 @@ -65,7 +65,7 @@ else: usemodules = ['thread'] space = StdObjSpace(nofaking=True, - compiler="_stable", # lib/_stablecompiler + compiler="ast", # interpreter/astcompiler translating=True, usemodules=usemodules, geninterp=geninterp) From ericvrp at codespeak.net Tue Oct 4 21:07:06 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 4 Oct 2005 21:07:06 +0200 (CEST) Subject: [pypy-svn] r18164 - in pypy/dist/pypy/translator/llvm: . backendopt Message-ID: <20051004190706.2728C27B57@code1.codespeak.net> Author: ericvrp Date: Tue Oct 4 21:07:05 2005 New Revision: 18164 Modified: pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py pypy/dist/pypy/translator/llvm/exception.py Log: * exception handling policies renamed. CPython -> invokeunwind fast -> explicit * cleanup logging. Modified: pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py ============================================================================== --- pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py (original) +++ pypy/dist/pypy/translator/llvm/backendopt/removeexcmallocs.py Tue Oct 4 21:07:05 2005 @@ -17,6 +17,7 @@ an exception instance 'long' after it has been raised. """ n_removed = 0 + n_removed_of_type = {} blocks = [x for x in flatten(graph) if isinstance(x, Block)] for block in blocks: ops = block.operations @@ -28,8 +29,14 @@ name = str(ops[0].args[0]) if 'Exception' not in name and 'Error' not in name: #XXX better to look at the actual structure continue - log.removeexceptionmallocs('%s from function %s' % (name, ref)) + #log.removeexceptionmallocs('%s from function %s' % (name, ref)) ops[0].opname = 'malloc_exception' #XXX refactor later to not use a new operationtype n_removed += 1 + if name in n_removed_of_type: n_removed_of_type[name] += 1 + else: n_removed_of_type[name] = 1 + if n_removed: + log.removeexceptionmallocs('%dx' % (n_removed,)) + for k,v in n_removed_of_type.iteritems(): + log.removeexceptionmallocs(' -> %dx %s' % (v, k)) return n_removed Modified: pypy/dist/pypy/translator/llvm/exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm/exception.py (original) +++ pypy/dist/pypy/translator/llvm/exception.py Tue Oct 4 21:07:05 2005 @@ -49,13 +49,13 @@ return noresult def new(exceptionpolicy=None): #factory - exceptionpolicy = exceptionpolicy or 'fast' - if exceptionpolicy == 'cpython': - from pypy.translator.llvm.exception import CPythonExceptionPolicy - exceptionpolicy = CPythonExceptionPolicy() - elif exceptionpolicy == 'fast': - from pypy.translator.llvm.exception import FastExceptionPolicy - exceptionpolicy = FastExceptionPolicy() + exceptionpolicy = exceptionpolicy or 'explicit' + if exceptionpolicy == 'invokeunwind': + from pypy.translator.llvm.exception import InvokeUnwindExceptionPolicy + exceptionpolicy = InvokeUnwindExceptionPolicy() + elif exceptionpolicy == 'explicit': + from pypy.translator.llvm.exception import ExplicitExceptionPolicy + exceptionpolicy = ExplicitExceptionPolicy() elif exceptionpolicy == 'none': from pypy.translator.llvm.exception import NoneExceptionPolicy exceptionpolicy = NoneExceptionPolicy() @@ -70,7 +70,7 @@ pass -class CPythonExceptionPolicy(ExceptionPolicy): #uses issubclass() and llvm invoke&unwind +class InvokeUnwindExceptionPolicy(ExceptionPolicy): #uses issubclass() and llvm invoke&unwind def __init__(self): pass @@ -160,7 +160,7 @@ return '-enable-correct-eh-support' -class FastExceptionPolicy(ExceptionPolicy): #uses issubclass() and last_exception tests after each call +class ExplicitExceptionPolicy(ExceptionPolicy): #uses issubclass() and last_exception tests after each call def __init__(self): self.invoke_count = 0 From pedronis at codespeak.net Tue Oct 4 21:27:04 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 4 Oct 2005 21:27:04 +0200 (CEST) Subject: [pypy-svn] r18165 - pypy/dist/pypy Message-ID: <20051004192704.56C8927B57@code1.codespeak.net> Author: pedronis Date: Tue Oct 4 21:27:02 2005 New Revision: 18165 Modified: pypy/dist/pypy/conftest.py Log: anotather place needing a default compiler check (we really need to unify our pypy option handling) Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Tue Oct 4 21:27:02 2005 @@ -37,7 +37,7 @@ callback=usemodules_callback, default=[], help="(mixed) modules to use."), Option('--compiler', action="store", type="string", dest="compiler", - metavar="[stable|_stable|ast|cpython]", default='stable', + metavar="[stable|_stable|ast|cpython]", default='ast', help="""select compiling approach. see pypy/doc/README.compiling""") ) From cfbolz at codespeak.net Tue Oct 4 21:48:33 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 21:48:33 +0200 (CEST) Subject: [pypy-svn] r18166 - pypy/dist/pypy/translator/tool/pygame Message-ID: <20051004194833.4717027B58@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 21:48:32 2005 New Revision: 18166 Modified: pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Log: I guess the redraw should be done _after_ the reload. 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 Tue Oct 4 21:48:32 2005 @@ -420,8 +420,8 @@ def reload(self): self.setstatusbar('reloading...') - self.redraw_now() self.layout.request_reload() + self.redraw_now() def setstatusbar(self, text, fgcolor=None, bgcolor=None): info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) From cfbolz at codespeak.net Tue Oct 4 21:53:56 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 21:53:56 +0200 (CEST) Subject: [pypy-svn] r18167 - pypy/dist/pypy/translator/tool/pygame Message-ID: <20051004195356.E2F8F27B58@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 21:53:55 2005 New Revision: 18167 Modified: pypy/dist/pypy/translator/tool/pygame/graphclient.py Log: don't crash when reloading 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 Tue Oct 4 21:53:55 2005 @@ -52,7 +52,9 @@ # failed, try via codespeak dot2plain(dotfilename, PLAIN_FILE, use_codespeak=True) GraphLayout.__init__(self, PLAIN_FILE) - + + def request_reload(self): + pass class ClientGraphLayout(DotGraphLayout): From ac at codespeak.net Tue Oct 4 21:59:22 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 4 Oct 2005 21:59:22 +0200 (CEST) Subject: [pypy-svn] r18169 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20051004195922.9BA9427B58@code1.codespeak.net> Author: ac Date: Tue Oct 4 21:59:22 2005 New Revision: 18169 Modified: pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py Log: Use the correct token linenumber. Modified: pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/tuplebuilder.py Tue Oct 4 21:59:22 2005 @@ -95,7 +95,7 @@ return True def token(self, codename, value, source): - lineno = source.current_lineno() + lineno = source._token_lnum if value is None: if codename not in ( NEWLINE, INDENT, DEDENT, ENDMARKER ): value = tok_rpunct.get(codename, "unknown op") From pedronis at codespeak.net Tue Oct 4 22:34:14 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 4 Oct 2005 22:34:14 +0200 (CEST) Subject: [pypy-svn] r18170 - in pypy/dist/pypy: rpython translator/backendopt/test Message-ID: <20051004203414.1BCC127B5A@code1.codespeak.net> Author: pedronis Date: Tue Oct 4 22:34:11 2005 New Revision: 18170 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/translator/backendopt/test/test_all.py Log: - let the llinterp better emulate the lifetime property realised by the backends, value not passed to the next block should not be kept alive - in-progress test about lifetime/inlining interaction issues Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Oct 4 22:34:11 2005 @@ -109,6 +109,9 @@ # _______________________________________________________ # variable setters/getters helpers + def clear(self): + self.bindings.clear() + def fillvars(self, block, values): vars = block.inputargs assert len(vars) == len(values), ( @@ -150,6 +153,7 @@ nextblock = graph.startblock args = self.args while 1: + self.clear() self.fillvars(nextblock, args) nextblock, args = self.eval_block(nextblock) if nextblock is None: Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_all.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_all.py Tue Oct 4 22:34:11 2005 @@ -3,6 +3,7 @@ from pypy.translator.backendopt.test.test_malloc import check_malloc_removed from pypy.translator.translator import Translator from pypy.objspace.flow.model import Constant +from pypy.annotation import model as annmodel from pypy.rpython.llinterp import LLInterpreter @@ -88,3 +89,42 @@ interp = LLInterpreter(t.flowgraphs, t.rtyper) res = interp.eval_function(f, [11, 22]) assert res == 33 + +def inprogress_test_premature_death(): + import os + from pypy.annotation import listdef + + ldef = listdef.ListDef(None, annmodel.SomeString()) + inputtypes = [annmodel.SomeList(ldef)] + + def debug(msg): + os.write(2, "debug: " + msg + '\n') + + def entry_point(argv): + #debug("entry point starting") + for arg in argv: + #debug(" argv -> " + arg) + r = arg.replace('_', '-') + #debug(' replaced -> ' + r) + a = r.lower() + #debug(" lowered -> " + a) + return 0 + + t = Translator(entry_point) + t.annotate(inputtypes) + t.specialize() + t.backend_optimizations(inline_threshold=1, mallocs=True) + + graph = t.getflowgraph() + + from pypy.rpython.module.support import to_rstr + + argv = t.rtyper.getrepr(inputtypes[0]).convert_const(['./pypy-c']) + + interp = LLInterpreter(t.flowgraphs, t.rtyper) + interp.eval_function(entry_point, [argv]) + + + + + From rxe at codespeak.net Tue Oct 4 22:56:24 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Tue, 4 Oct 2005 22:56:24 +0200 (CEST) Subject: [pypy-svn] r18171 - pypy/dist/pypy/doc Message-ID: <20051004205624.9119427B5A@code1.codespeak.net> Author: rxe Date: Tue Oct 4 22:56:22 2005 New Revision: 18171 Modified: pypy/dist/pypy/doc/contact.txt Log: Fix irc log link. Modified: pypy/dist/pypy/doc/contact.txt ============================================================================== --- pypy/dist/pypy/doc/contact.txt (original) +++ pypy/dist/pypy/doc/contact.txt Tue Oct 4 22:56:22 2005 @@ -34,4 +34,4 @@ 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 +.. _here: http://tismerysoft.de/pypy/irc-logs/pypy \ No newline at end of file From cfbolz at codespeak.net Tue Oct 4 22:57:06 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 22:57:06 +0200 (CEST) Subject: [pypy-svn] r18172 - pypy/dist/pypy/translator/tool/pygame Message-ID: <20051004205706.F266127B5A@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 22:57:05 2005 New Revision: 18172 Modified: pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Log: revert this. the redraw is to show the status line "reloading..." armin told me that the layout should issue a reload itself, if it wants one (thanks) 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 Tue Oct 4 22:57:05 2005 @@ -420,8 +420,8 @@ def reload(self): self.setstatusbar('reloading...') - self.layout.request_reload() self.redraw_now() + self.layout.request_reload() def setstatusbar(self, text, fgcolor=None, bgcolor=None): info = (text, fgcolor or self.STATUSBAR_FGCOLOR, bgcolor or self.STATUSBAR_BGCOLOR) From nico at codespeak.net Tue Oct 4 23:07:40 2005 From: nico at codespeak.net (nico at codespeak.net) Date: Tue, 4 Oct 2005 23:07:40 +0200 (CEST) Subject: [pypy-svn] r18173 - pypy/extradoc/talk Message-ID: <20051004210740.70AB427B5C@code1.codespeak.net> Author: nico Date: Tue Oct 4 23:07:39 2005 New Revision: 18173 Modified: pypy/extradoc/talk/conference-attendance.txt Log: added solution linux talk Modified: pypy/extradoc/talk/conference-attendance.txt ============================================================================== --- pypy/extradoc/talk/conference-attendance.txt (original) +++ pypy/extradoc/talk/conference-attendance.txt Tue Oct 4 23:07:39 2005 @@ -18,6 +18,13 @@ Time & Location: 27th-30th December, Berlin. +Solution Linux 2006 +------------------- + +Logilab will present PyPy in the "free software models" track. + +Time and Location: 31st jan to feb 2nd, Paris. + Pycon 2006 --------------- From arigo at codespeak.net Tue Oct 4 23:13:54 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 4 Oct 2005 23:13:54 +0200 (CEST) Subject: [pypy-svn] r18174 - pypy/extradoc/sprintinfo Message-ID: <20051004211354.524BC27B60@code1.codespeak.net> Author: arigo Date: Tue Oct 4 23:13:51 2005 New Revision: 18174 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: my info, and other people's accomodation as discussed today on IRC and pypy-sprint. Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Tue Oct 4 23:13:51 2005 @@ -16,16 +16,16 @@ Jacob Hallen 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Laura Creighton 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Beatrice Duering 9/10 - 17/10 flat -Armin Rigo ? ? +Armin Rigo 8/10 - 17/10 booking... Samuele Pedroni 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Anders Chrigstroem 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Holger Krekel 6th-17th Oct flat Lene Wagner 12th-13th Oct flat -Michael Hudson ? ? -Carl Friedrich Bolz 7/10? - 16/10 flat? -Bert Freudenberg 09/10 - 17/10 ? +Michael Hudson ? flat +Carl Friedrich Bolz 7/10? - 16/10 flat +Bert Freudenberg 09/10 - 17/10 with Armin Anders Lehmann 09/10 - 14/10 Hotel Porte de Versailles -Boris Feigin 09/10 - 16/10 ?/looking for flatmates +Boris Feigin 09/10 - 16/10 hotel Amaury Forgeot d'Arc 10/10 - 16/10 Private Andrew Thompson 09/10 - 17/10 Citea Vanves Portes de Versailles Christian Tismer 09/10 - 16/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) From ac at codespeak.net Tue Oct 4 23:34:30 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 4 Oct 2005 23:34:30 +0200 (CEST) Subject: [pypy-svn] r18175 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20051004213430.C796127B5C@code1.codespeak.net> Author: ac Date: Tue Oct 4 23:34:30 2005 New Revision: 18175 Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py Log: Account for a possibly empty string. Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonparse.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonparse.py Tue Oct 4 23:34:30 2005 @@ -39,7 +39,7 @@ lines = [line + '\n' for line in textsrc.split('\n')] builder.source_encoding = enc - if textsrc[-1] =='\n': + if len(textsrc) and textsrc[-1] == '\n': lines.pop() flags &= ~PyCF_DONT_IMPLY_DEDENT return self.parse_lines(lines, goal, builder, flags) From cfbolz at codespeak.net Tue Oct 4 23:52:04 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 4 Oct 2005 23:52:04 +0200 (CEST) Subject: [pypy-svn] r18176 - in pypy/dist/pypy: bin translator/tool/pygame Message-ID: <20051004215204.6213127B5C@code1.codespeak.net> Author: cfbolz Date: Tue Oct 4 23:52:02 2005 New Revision: 18176 Modified: pypy/dist/pypy/bin/dotviewer.py pypy/dist/pypy/translator/tool/pygame/graphclient.py Log: * changed the DotGraphViewer to issue redraws after the reload * added a class ReloadingGraphViewer, that checks for changes to the dot file every second and issues reload events if necessary * added optparse option parsing to dotviewer.py: added an option --reload that uses ReloadingGraphViewer instead of DotGraphViewer Modified: pypy/dist/pypy/bin/dotviewer.py ============================================================================== --- pypy/dist/pypy/bin/dotviewer.py (original) +++ pypy/dist/pypy/bin/dotviewer.py Tue Oct 4 23:52:02 2005 @@ -8,25 +8,36 @@ import sys, py from pypy.translator.tool.pygame import graphclient +from py.compat import optparse + +usage = ''' + %s filename.dot + %s hostname:port + %s :port + +In the first form, show the graph contained in a .dot file. +In the other forms, connect to a graph server like +goal/translate_pypy +''' % (sys.argv[0], sys.argv[0], sys.argv[0]) + +parser = optparse.OptionParser(usage=usage) +parser.add_option("--reload", action="store_true", dest="reload", + default=False, help="reload the dot file continously") + if __name__ == '__main__': - if len(sys.argv) != 2: - print >> sys.stderr, 'Usage: %s filename.dot' % (sys.argv[0],) - print >> sys.stderr, ' %s hostname:port' % (sys.argv[0],) - print >> sys.stderr, ' %s :port' % (sys.argv[0],) - print >> sys.stderr - print >> sys.stderr, ('In the first form, show the graph contained ' - 'in a .dot file.') - print >> sys.stderr, ('In the other forms, connect to a graph server ' - 'like goal/translate_pypy.') + options, args = parser.parse_args() + if len(args) != 1: + parser.error("too many options") sys.exit(2) - filename = sys.argv[1] + filename = args[0] if py.path.local(filename).check(): - graphclient.display_dot_file(filename) + graphclient.display_dot_file(filename, + reload_repeatedly=options.reload) elif filename.count(':') != 1: print >> sys.stderr, 'No such file:', filename sys.exit(1) else: - hostname, port = sys.argv[1].split(':') + hostname, port = args[0].split(':') port = int(port) graphclient.display_remote_layout(hostname, port) 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 Tue Oct 4 23:52:02 2005 @@ -45,6 +45,7 @@ """A graph layout computed by dot from a .dot file. """ def __init__(self, dotfilename): + self.dotfilename = py.path.local(dotfilename) try: dot2plain(dotfilename, PLAIN_FILE, use_codespeak=False) GraphLayout.__init__(self, PLAIN_FILE) @@ -54,14 +55,56 @@ GraphLayout.__init__(self, PLAIN_FILE) def request_reload(self): - pass + self.__init__(self.dotfilename) + display_async_cmd(layout=self) +class ReloadingDotGraphLayout(DotGraphLayout): + """A graph layout computed by dot from a .dot file. + when a reload is requested, it checks whether the date of the dotfile + is newer that the saved date and reloads the dot file, if that is the + case""" + # XXX XXX XXX + # this class is a bit hackish and should not be used outside of the dotviewer.py + # environment + def __init__(self, dotfilename): + import pygame + import pygame.locals + self.ev1 = pygame.event.Event(pygame.KEYDOWN, key=pygame.locals.K_q, mod=0, + unicode=u"r") + self.ev2 = pygame.event.Event(pygame.KEYUP) + self.stop = False + DotGraphLayout.__init__(self, dotfilename) + + def get_display(self): + from pypy.translator.tool.pygame.graphdisplay import GraphDisplay + import threading + display = GraphDisplay(self) + thread = threading.Thread(target=self.issue_reloads, args=[display]) + thread.start() + return display + + def issue_reloads(self, display): + print "starting issue_reloads" + import time, pygame + mtime = self.dotfilename.stat().mtime + while 1: + time.sleep(1) + newmtime = self.dotfilename.stat().mtime + if newmtime > mtime: + mtime = newmtime + pygame.event.post(self.ev1) + pygame.event.post(self.ev2) + if self.stop: + break + class ClientGraphLayout(DotGraphLayout): def __init__(self, connexion, key, dot, links, **ignored): # generate a temporary .dot file and call dot on it DOT_FILE.write(dot) DotGraphLayout.__init__(self, DOT_FILE) + self.mtime = self.dotfilename.stat().mtime + DotGraphLayout.__init__(self, dotfilename) self.connexion = connexion self.key = key self.links.update(links) @@ -128,9 +171,15 @@ conn.initiate_display(0) display.run() -def display_dot_file(filename): - display = DotGraphLayout(filename).get_display() - display.run() +def display_dot_file(filename, reload_repeatedly=False): + if reload_repeatedly: + layout = ReloadingDotGraphLayout(filename) + display = layout.get_display() + display.run() + layout.stop = True + else: + display = DotGraphLayout(filename).get_display() + display.run() if __name__ == '__main__': From pedronis at codespeak.net Tue Oct 4 23:53:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 4 Oct 2005 23:53:13 +0200 (CEST) Subject: [pypy-svn] r18177 - in pypy/dist/pypy: annotation rpython rpython/test translator translator/backendopt translator/backendopt/test translator/c translator/c/test Message-ID: <20051004215313.032E427B5C@code1.codespeak.net> Author: pedronis Date: Tue Oct 4 23:53:06 2005 New Revision: 18177 Modified: pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/test/test_objectmodel.py pypy/dist/pypy/translator/backendopt/malloc.py pypy/dist/pypy/translator/backendopt/test/test_malloc.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/test/test_genc.py pypy/dist/pypy/translator/simplify.py Log: introduced a keepalive objectmodel function and ll operation to have lifetime control and to be used to avoud premature garbage collection (for example with inlining, which is next to fix using this) Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Tue Oct 4 23:53:06 2005 @@ -254,6 +254,10 @@ f, rinputs, rresult = r_func.get_signature() return lltype_to_annotation(rresult.lowleveltype) +def robjmodel_keepalive(*args_s): + return immutablevalue(None) + + ##def rarith_ovfcheck(s_obj): ## if isinstance(s_obj, SomeInteger) and s_obj.unsigned: ## getbookkeeper().warning("ovfcheck on unsigned") @@ -294,6 +298,7 @@ robjmodel_we_are_translated) BUILTIN_ANALYZERS[pypy.rpython.objectmodel.r_dict] = robjmodel_r_dict BUILTIN_ANALYZERS[pypy.rpython.objectmodel.hlinvoke] = robjmodel_hlinvoke +BUILTIN_ANALYZERS[pypy.rpython.objectmodel.keepalive] = robjmodel_keepalive BUILTIN_ANALYZERS[Exception.__init__.im_func] = exception_init BUILTIN_ANALYZERS[OSError.__init__.im_func] = exception_init Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Oct 4 23:53:06 2005 @@ -259,6 +259,9 @@ # __________________________________________________________ # misc LL operation implementations + def op_keepalive(self, *values): + pass + def op_same_as(self, x): return x Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Tue Oct 4 23:53:06 2005 @@ -17,6 +17,9 @@ return False # annotation -> True +def keepalive(*values): + pass + class FREED_OBJECT(object): def __getattribute__(self, attr): Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Tue Oct 4 23:53:06 2005 @@ -394,3 +394,10 @@ return hop.genop('flavored_free', [cflavor, vinst]) BUILTIN_TYPER[objectmodel.free_non_gc_object] = rtype_free_non_gc_object + +# keepalive + +def rtype_keepalive(hop): + return hop.genop('keepalive', hop.args_v, resulttype=lltype.Void) + +BUILTIN_TYPER[objectmodel.keepalive] = rtype_keepalive Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Tue Oct 4 23:53:06 2005 @@ -141,3 +141,14 @@ assert res == 1 res = interpret(fn, [2]) assert res == 2 + +def test_rtype_keepalive(): + from pypy.rpython import objectmodel + def f(): + x = [1] + y = ['b'] + objectmodel.keepalive(x,y) + return 1 + + res = interpret(f, []) + assert res == 1 Modified: pypy/dist/pypy/translator/backendopt/malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/malloc.py Tue Oct 4 23:53:06 2005 @@ -108,12 +108,16 @@ STRUCT = lltypes.keys()[0].TO assert isinstance(STRUCT, lltype.GcStruct) - # must be only ever accessed via getfield/setfield + # must be only ever accessed via getfield/setfield or touched by keepalive for up in info.usepoints: if up[0] != "op": return False - if (up[2].opname, up[3]) not in [("getfield", 0), ("setfield", 0)]: - return False + kind, node, op, index = up + if op.opname == 'keepalive': + continue + if (op.opname, index) in [("getfield", 0), ("setfield", 0)]: + continue + return False # success: replace each variable with a family of variables (one per field) example = STRUCT._container_example() @@ -172,6 +176,8 @@ # equivalent. We can, and indeed must, use the same # flattened list of variables for both, as a "setfield" # via one pointer must be reflected in the other. + elif op.opname == 'keepalive': + pass else: raise AssertionError, op.opname elif op.result in vars: Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Tue Oct 4 23:53:06 2005 @@ -97,3 +97,15 @@ a.x = 12 return a1.x check(fn6, [int], [1], 12, must_be_removed=False) + +def test_with_keepalive(): + from pypy.rpython.objectmodel import keepalive + def fn1(x, y): + if x > 0: + t = x+y, x-y + else: + t = x-y, x+y + s, d = t + keepalive(t) + return s*d + check(fn1, [int, int], [15, 10], 125) Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Tue Oct 4 23:53:06 2005 @@ -538,6 +538,9 @@ result.append(self.pyobj_incref(op.result)) return '\t'.join(result) + def OP_KEEPALIVE(self, op, err): # xxx what should be the sematics consequences of this + return "/* kept alive: %s */ ;" % ''.join([self.expr(v, special_case_void=False) for v in op.args]) + def pyobj_incref(self, v): T = self.lltypemap(v) return self.pyobj_incref_expr(LOCALVAR % v.name, T) 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 Oct 4 23:53:06 2005 @@ -237,3 +237,15 @@ for i, s in enumerate(choices): for j, c in enumerate(s): assert f1(i, j) == c + + +def test_keepalive(): + from pypy.rpython import objectmodel + def f(): + x = [1] + y = ['b'] + objectmodel.keepalive(x,y) + return 1 + + f1 = compile(f, []) + assert f1() == 1 Modified: pypy/dist/pypy/translator/simplify.py ============================================================================== --- pypy/dist/pypy/translator/simplify.py (original) +++ pypy/dist/pypy/translator/simplify.py Tue Oct 4 23:53:06 2005 @@ -349,6 +349,7 @@ # decide whether a function has side effects lloperations_with_side_effects = {"setfield": True, "setarrayitem": True, + "keepalive": True, } class HasSideEffects(Exception): From pedronis at codespeak.net Wed Oct 5 01:28:23 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 5 Oct 2005 01:28:23 +0200 (CEST) Subject: [pypy-svn] r18178 - in pypy/dist/pypy: rpython translator/backendopt translator/backendopt/test translator/c Message-ID: <20051004232823.1C95727B5C@code1.codespeak.net> Author: pedronis Date: Wed Oct 5 01:28:19 2005 New Revision: 18178 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/test/test_all.py pypy/dist/pypy/translator/backendopt/test/test_propagate.py pypy/dist/pypy/translator/c/funcgen.py Log: keepalive space op should take just one variable, change inline to insert keepalive ops to preserve the lifetime properties Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 5 01:28:19 2005 @@ -259,7 +259,7 @@ # __________________________________________________________ # misc LL operation implementations - def op_keepalive(self, *values): + def op_keepalive(self, value): pass def op_same_as(self, x): Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Wed Oct 5 01:28:19 2005 @@ -398,6 +398,8 @@ # keepalive def rtype_keepalive(hop): - return hop.genop('keepalive', hop.args_v, resulttype=lltype.Void) + for v in hop.args_v: + hop.genop('keepalive', hop.args_v, resulttype=lltype.Void) + return hop.inputconst(lltype.Void, None) BUILTIN_TYPER[objectmodel.keepalive] = rtype_keepalive Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Wed Oct 5 01:28:19 2005 @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import SpaceOperation, last_exception from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph, flatten from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Bool, typeOf +from pypy.rpython.lltype import Bool, typeOf, Void from pypy.rpython import rmodel from pypy.tool.algo import sparsemat from pypy.translator.backendopt.support import log @@ -62,7 +62,7 @@ def _find_exception_type(block): #XXX slightly brittle: find the exception type for simple cases #(e.g. if you do only raise XXXError) by doing pattern matching - ops = block.operations + ops = [op for op in block.operations if op.opname != 'keepalive'] if (len(ops) < 6 or ops[-6].opname != "malloc" or ops[-5].opname != "cast_pointer" or ops[-4].opname != "setfield" or ops[-3].opname != "cast_pointer" or @@ -129,6 +129,14 @@ if hasattr(link, 'llexitcase'): newlink.llexitcase = link.llexitcase return newlink + def generate_keepalive(vars): + keepalive_ops = [] + for v in vars: + v_keepalive = Variable() + v_keepalive.concretetype = Void + keepalive_ops.append(SpaceOperation('keepalive', [v], v_keepalive)) + return keepalive_ops + linktoinlined = beforeblock.exits[0] assert linktoinlined.target is afterblock copiedstartblock = copy_block(graph_to_inline.startblock) @@ -146,7 +154,7 @@ linktoinlined.target = copiedstartblock linktoinlined.args = passon_args afterblock.inputargs = [op.result] + afterblock.inputargs - afterblock.operations = afterblock.operations[1:] + afterblock.operations = generate_keepalive(afterblock.inputargs) + afterblock.operations[1:] if graph_to_inline.returnblock in entrymap: copiedreturnblock = copied_blocks[graph_to_inline.returnblock] linkfrominlined = Link([copiedreturnblock.inputargs[0]] + passon_vars[graph_to_inline.returnblock], afterblock) @@ -193,6 +201,7 @@ #try to match the exceptions for simple cases for link in entrymap[graph_to_inline.exceptblock]: copiedblock = copied_blocks[link.prevblock] + copiedblock.operations += generate_keepalive(passon_vars[link.prevblock]) copiedlink = copiedblock.exits[0] eclass = _find_exception_type(copiedblock) #print copiedblock.operations @@ -242,6 +251,7 @@ blocks[-1].exitswitch = None linkargs = copiedexceptblock.inputargs copiedexceptblock.closeblock(Link(linkargs, blocks[0])) + copiedexceptblock.operations += generate_keepalive(linkargs) afterblock.exits = [afterblock.exits[0]] afterblock.exitswitch = None #cleaning up -- makes sense to be here, because I insert quite Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_all.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_all.py Wed Oct 5 01:28:19 2005 @@ -90,7 +90,7 @@ res = interp.eval_function(f, [11, 22]) assert res == 33 -def inprogress_test_premature_death(): +def test_premature_death(): import os from pypy.annotation import listdef Modified: pypy/dist/pypy/translator/backendopt/test/test_propagate.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_propagate.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_propagate.py Wed Oct 5 01:28:19 2005 @@ -66,7 +66,7 @@ graph, t = get_graph(g, [int]) while constant_folding(graph, t): pass - assert len(graph.startblock.operations) == 1 + assert len(graph.startblock.operations) == 4 check_graph(graph, [10], g(10), t) def test_fold_const_blocks(): @@ -82,7 +82,7 @@ graph, t = get_graph(g, [int]) partial_folding(graph, t) constant_folding(graph, t) - assert len(graph.startblock.operations) == 1 + assert len(graph.startblock.operations) == 3 check_graph(graph, [10], g(10), t) def getitem(l, i): #LookupError, KeyError Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Wed Oct 5 01:28:19 2005 @@ -539,7 +539,7 @@ return '\t'.join(result) def OP_KEEPALIVE(self, op, err): # xxx what should be the sematics consequences of this - return "/* kept alive: %s */ ;" % ''.join([self.expr(v, special_case_void=False) for v in op.args]) + return "/* kept alive: %s */ ;" % self.expr(op.args[0], special_case_void=False) def pyobj_incref(self, v): T = self.lltypemap(v) From cfbolz at codespeak.net Wed Oct 5 01:41:45 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 5 Oct 2005 01:41:45 +0200 (CEST) Subject: [pypy-svn] r18179 - pypy/dist/pypy/translator/tool/pygame Message-ID: <20051004234145.705CF27B5C@code1.codespeak.net> Author: cfbolz Date: Wed Oct 5 01:41:44 2005 New Revision: 18179 Modified: pypy/dist/pypy/translator/tool/pygame/graphclient.py Log: argh! what a nonsense. 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 Wed Oct 5 01:41:44 2005 @@ -103,8 +103,6 @@ # generate a temporary .dot file and call dot on it DOT_FILE.write(dot) DotGraphLayout.__init__(self, DOT_FILE) - self.mtime = self.dotfilename.stat().mtime - DotGraphLayout.__init__(self, dotfilename) self.connexion = connexion self.key = key self.links.update(links) From arigo at codespeak.net Wed Oct 5 02:04:51 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 5 Oct 2005 02:04:51 +0200 (CEST) Subject: [pypy-svn] r18180 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20051005000451.4981927B5C@code1.codespeak.net> Author: arigo Date: Wed Oct 5 02:04:45 2005 New Revision: 18180 Modified: pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/malloc.py pypy/dist/pypy/translator/backendopt/propagate.py pypy/dist/pypy/translator/backendopt/test/test_inline.py pypy/dist/pypy/translator/backendopt/test/test_propagate.py Log: Polishing... and for inlining, count the "cost" of a block better than just len(block.operations). Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Wed Oct 5 02:04:45 2005 @@ -4,7 +4,7 @@ from pypy.translator.unsimplify import copyvar, split_block from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, last_exception -from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph, flatten +from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph from pypy.annotation import model as annmodel from pypy.rpython.lltype import Bool, typeOf, Void from pypy.rpython import rmodel @@ -264,17 +264,31 @@ # # Automatic inlining +OP_WEIGHTS = {'same_as': 0, + 'cast_pointer': 0, + 'keepalive': 0, + 'direct_call': 2, # guess + } + +def block_weight(block, weights=OP_WEIGHTS): + total = 0 + for op in block.operations: + total += weights.get(op.opname, 1) + if block.exitswitch is not None: + total += 1 + return total + + def measure_median_execution_cost(graph): blocks = [] blockmap = {} - for node in flatten(graph): - if isinstance(node, Block): - blockmap[node] = len(blocks) - blocks.append(node) + for block in graph.iterblocks(): + blockmap[block] = len(blocks) + blocks.append(block) M = sparsemat.SparseMatrix(len(blocks)) vector = [] for i, block in enumerate(blocks): - vector.append(len(block.operations)) + vector.append(block_weight(block)) M[i, i] = 1 if block.exits: f = 1.0 / len(block.exits) @@ -291,9 +305,8 @@ def static_instruction_count(graph): count = 0 - for node in flatten(graph): - if isinstance(node, Block): - count += len(node.operations) + for block in graph.iterblocks(): + count += block_weight(block) return count def inlining_heuristic(graph): Modified: pypy/dist/pypy/translator/backendopt/malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/malloc.py Wed Oct 5 02:04:45 2005 @@ -113,10 +113,10 @@ if up[0] != "op": return False kind, node, op, index = up - if op.opname == 'keepalive': - continue - if (op.opname, index) in [("getfield", 0), ("setfield", 0)]: - continue + if (op.opname, index) in [("getfield", 0), + ("setfield", 0), + ("keepalive", 0)]: + continue # ok return False # success: replace each variable with a family of variables (one per field) Modified: pypy/dist/pypy/translator/backendopt/propagate.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/propagate.py (original) +++ pypy/dist/pypy/translator/backendopt/propagate.py Wed Oct 5 02:04:45 2005 @@ -6,6 +6,7 @@ from pypy.translator import simplify from pypy.translator.backendopt.tailrecursion import get_graph from pypy.translator.backendopt.removenoops import remove_same_as +from pypy.translator.backendopt.inline import OP_WEIGHTS def do_atmost(n, f, *args): i = 0 @@ -138,7 +139,7 @@ def eval_operation(self, operation): if operation is None: #can happen in the middle of constant folding return - self.count += 1 + self.count += OP_WEIGHTS.get(operation.opname, 1) if self.count > self.maxcount: raise TooManyOperations return super(CountingLLFrame, self).eval_operation(operation) Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_inline.py Wed Oct 5 02:04:45 2005 @@ -326,4 +326,4 @@ return x t = Translator(f) res = measure_median_execution_cost(t.getflowgraph()) - assert res == 17 + assert res == 19 Modified: pypy/dist/pypy/translator/backendopt/test/test_propagate.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_propagate.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_propagate.py Wed Oct 5 02:04:45 2005 @@ -66,7 +66,7 @@ graph, t = get_graph(g, [int]) while constant_folding(graph, t): pass - assert len(graph.startblock.operations) == 4 + assert len(graph.startblock.operations) == 1 check_graph(graph, [10], g(10), t) def test_fold_const_blocks(): From pedronis at codespeak.net Wed Oct 5 02:15:21 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 5 Oct 2005 02:15:21 +0200 (CEST) Subject: [pypy-svn] r18181 - in pypy/dist/pypy: annotation rpython rpython/test translator translator/backendopt/test translator/c/test Message-ID: <20051005001521.272CE27B5C@code1.codespeak.net> Author: pedronis Date: Wed Oct 5 02:15:16 2005 New Revision: 18181 Modified: pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/test/test_objectmodel.py pypy/dist/pypy/translator/backendopt/test/test_malloc.py pypy/dist/pypy/translator/c/test/test_genc.py pypy/dist/pypy/translator/simplify.py Log: - rename keepalive the function to the more explcit keepalive_until_here () (the op is still just keepalive) - keepalive op has indeed no side-effects Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Wed Oct 5 02:15:16 2005 @@ -254,7 +254,7 @@ f, rinputs, rresult = r_func.get_signature() return lltype_to_annotation(rresult.lowleveltype) -def robjmodel_keepalive(*args_s): +def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) @@ -298,7 +298,7 @@ robjmodel_we_are_translated) BUILTIN_ANALYZERS[pypy.rpython.objectmodel.r_dict] = robjmodel_r_dict BUILTIN_ANALYZERS[pypy.rpython.objectmodel.hlinvoke] = robjmodel_hlinvoke -BUILTIN_ANALYZERS[pypy.rpython.objectmodel.keepalive] = robjmodel_keepalive +BUILTIN_ANALYZERS[pypy.rpython.objectmodel.keepalive_until_here] = robjmodel_keepalive_until_here BUILTIN_ANALYZERS[Exception.__init__.im_func] = exception_init BUILTIN_ANALYZERS[OSError.__init__.im_func] = exception_init Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Wed Oct 5 02:15:16 2005 @@ -17,7 +17,7 @@ return False # annotation -> True -def keepalive(*values): +def keepalive_until_here(*values): pass Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Wed Oct 5 02:15:16 2005 @@ -395,11 +395,11 @@ BUILTIN_TYPER[objectmodel.free_non_gc_object] = rtype_free_non_gc_object -# keepalive +# keepalive_until_here -def rtype_keepalive(hop): +def rtype_keepalive_until_here(hop): for v in hop.args_v: - hop.genop('keepalive', hop.args_v, resulttype=lltype.Void) + hop.genop('keepalive', [v], resulttype=lltype.Void) return hop.inputconst(lltype.Void, None) -BUILTIN_TYPER[objectmodel.keepalive] = rtype_keepalive +BUILTIN_TYPER[objectmodel.keepalive_until_here] = rtype_keepalive_until_here Modified: pypy/dist/pypy/rpython/test/test_objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_objectmodel.py (original) +++ pypy/dist/pypy/rpython/test/test_objectmodel.py Wed Oct 5 02:15:16 2005 @@ -147,7 +147,7 @@ def f(): x = [1] y = ['b'] - objectmodel.keepalive(x,y) + objectmodel.keepalive_until_here(x,y) return 1 res = interpret(f, []) Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Wed Oct 5 02:15:16 2005 @@ -99,13 +99,13 @@ check(fn6, [int], [1], 12, must_be_removed=False) def test_with_keepalive(): - from pypy.rpython.objectmodel import keepalive + from pypy.rpython.objectmodel import keepalive_until_here def fn1(x, y): if x > 0: t = x+y, x-y else: t = x-y, x+y s, d = t - keepalive(t) + keepalive_until_here(t) return s*d check(fn1, [int, int], [15, 10], 125) 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 Wed Oct 5 02:15:16 2005 @@ -244,7 +244,7 @@ def f(): x = [1] y = ['b'] - objectmodel.keepalive(x,y) + objectmodel.keepalive_until_here(x,y) return 1 f1 = compile(f, []) Modified: pypy/dist/pypy/translator/simplify.py ============================================================================== --- pypy/dist/pypy/translator/simplify.py (original) +++ pypy/dist/pypy/translator/simplify.py Wed Oct 5 02:15:16 2005 @@ -349,8 +349,7 @@ # decide whether a function has side effects lloperations_with_side_effects = {"setfield": True, "setarrayitem": True, - "keepalive": True, - } + } class HasSideEffects(Exception): pass From tismer at codespeak.net Wed Oct 5 09:33:13 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 5 Oct 2005 09:33:13 +0200 (CEST) Subject: [pypy-svn] r18184 - pypy/extradoc/sprintinfo Message-ID: <20051005073313.5BA9127B60@code1.codespeak.net> Author: tismer Date: Wed Oct 5 09:33:12 2005 New Revision: 18184 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: new hotel info Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Wed Oct 5 09:33:12 2005 @@ -28,8 +28,8 @@ Boris Feigin 09/10 - 16/10 hotel Amaury Forgeot d'Arc 10/10 - 16/10 Private Andrew Thompson 09/10 - 17/10 Citea Vanves Portes de Versailles -Christian Tismer 09/10 - 16/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) - (most probably, have to call tomorrow morning, just one room left) +Christian Tismer 09/10 - 16/10 Hotel de l'Avenir, 65 rue Madame(+33 1 45 48 84 54) + booked a two-bed room, would like to share ==================== ============== ===================== People on the following list are likely to come and were From ericvrp at codespeak.net Wed Oct 5 10:25:42 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 5 Oct 2005 10:25:42 +0200 (CEST) Subject: [pypy-svn] r18185 - pypy/dist/pypy/translator/llvm/tool Message-ID: <20051005082542.A43CA27B60@code1.codespeak.net> Author: ericvrp Date: Wed Oct 5 10:25:42 2005 New Revision: 18185 Removed: pypy/dist/pypy/translator/llvm/tool/ Log: this tools is no longer required From ac at codespeak.net Wed Oct 5 11:55:19 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 5 Oct 2005 11:55:19 +0200 (CEST) Subject: [pypy-svn] r18186 - in pypy/dist/pypy/interpreter/pyparser: . test Message-ID: <20051005095519.C945B27B58@code1.codespeak.net> Author: ac Date: Wed Oct 5 11:55:19 2005 New Revision: 18186 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: Fix indexing with slices. Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Wed Oct 5 11:55:19 2005 @@ -913,12 +913,26 @@ # push arglist on the stack builder.push(atoms[1]) elif isinstance(first_token, TokenObject) and first_token.name == tok.LSQB: - if isinstance(atoms[1], SlicelistObject): + if len(atoms) == 3 and isinstance(atoms[1], SlicelistObject): builder.push(atoms[1]) else: subs = [] for index in range(1, len(atoms), 2): - subs.append(atoms[index]) + atom = atoms[index] + if isinstance(atom, SlicelistObject): + num_slicevals = 3 + slicevals = [] + if atom.fake_rulename == 'slice': + num_slicevals = 2 + for val in atom.value[:num_slicevals]: + if val is None: + slicevals.append(ast.Const(builder.wrap_none(), + atom.lineno)) + else: + slicevals.append(val) + subs.append(ast.Sliceobj(slicevals, atom.lineno)) + else: + subs.append(atom) builder.push(SubscriptObject('subscript', subs, first_token.lineno)) elif len(atoms) == 2: # Attribute access: '.' NAME 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 Oct 5 11:55:19 2005 @@ -267,6 +267,22 @@ "a.b.l[1:]", "a.b.l[:2]", "a.b.l[0:1:2]", + "a[1:2:3, 100]", + "a[:2:3, 100]", + "a[1::3, 100]", + "a[1:2:, 100]", + "a[1:2, 100]", + "a[1:, 100]", + "a[:2, 100]", + "a[:, 100]", + "a[100, 1:2:3]", + "a[100, :2:3]", + "a[100, 1::3]", + "a[100, 1:2:]", + "a[100, 1:2]", + "a[100, 1:]", + "a[100, :2]", + "a[100, :]", ] imports = [ From ericvrp at codespeak.net Wed Oct 5 12:04:59 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 5 Oct 2005 12:04:59 +0200 (CEST) Subject: [pypy-svn] r18188 - pypy/dist/pypy/translator/llvm/test Message-ID: <20051005100459.0747727B58@code1.codespeak.net> Author: ericvrp Date: Wed Oct 5 12:04:58 2005 New Revision: 18188 Modified: pypy/dist/pypy/translator/llvm/test/test_exception.py Log: Fix name of two tests that used to have the same name Modified: pypy/dist/pypy/translator/llvm/test/test_exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_exception.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_exception.py Wed Oct 5 12:04:58 2005 @@ -134,7 +134,7 @@ for i in range(10, 20): assert f(i) == fn(i) -def test_two_exceptions(): +def test_two_exceptionsA(): def fn(n): lst = range(10) try: @@ -194,12 +194,12 @@ for i in [-1, 0, 1, 2]: assert f(i) == i -def test_two_exceptions(): +def test_two_exceptionsB(): def fn1(): raise Exception def fn2(): return 10 - def two_exceptions(): + def two_exceptionsB(): r = 50 try: fn1() @@ -212,8 +212,8 @@ r += 300 r += fn2() return r - f = compile_function(two_exceptions, []) - assert f() == two_exceptions() + f = compile_function(two_exceptionsB, []) + assert f() == two_exceptionsB() def test_raise_outside_testfn(): def raiser(n): From ericvrp at codespeak.net Wed Oct 5 12:08:09 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 5 Oct 2005 12:08:09 +0200 (CEST) Subject: [pypy-svn] r18189 - pypy/dist/pypy/translator/llvm Message-ID: <20051005100809.F275127B58@code1.codespeak.net> Author: ericvrp Date: Wed Oct 5 12:08:09 2005 New Revision: 18189 Modified: pypy/dist/pypy/translator/llvm/exception.py pypy/dist/pypy/translator/llvm/opwriter.py Log: Changes to get keepalive operation to work. note: I think keepalive should not be allowed to be the last operation of blocks that have exitswitch Constant(last_exception) Modified: pypy/dist/pypy/translator/llvm/exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm/exception.py (original) +++ pypy/dist/pypy/translator/llvm/exception.py Wed Oct 5 12:08:09 2005 @@ -205,7 +205,8 @@ def invoke(self, codewriter, targetvar, tail_, cconv, returntype, functionref, args, label, except_label): if returntype == 'void': - codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args)) + if functionref != '%keepalive': #XXX I think keepalive should not be the last operation here! + codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args)) else: codewriter.indent('%s = %scall %s %s %s(%s)' % (targetvar, tail_, cconv, returntype, functionref, args)) tmp = '%%invoke.tmp.%d' % self.invoke_count Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Wed Oct 5 12:08:09 2005 @@ -132,6 +132,10 @@ targetvar = self.db.repr_arg(op.result) self.codewriter.cast(targetvar, mult_type, res_val, mult_type) + def _skipped(self, op): + self.codewriter.comment('***Skipping operation %s()' % (op.opname,)) + keepalive = _skipped + def int_abs(self, op): functionref = '%' + op.opname ExternalFuncNode.used_external_functions[functionref] = True @@ -442,7 +446,7 @@ ("uint", index)) self.codewriter.load(targetvar, targettype, tmpvar) else: - self.codewriter.comment("***Skipping operation getfield()***") + self._skipped(op) def getsubstruct(self, op): struct, structtype = self.db.repr_argwithtype(op.args[0]) @@ -465,7 +469,7 @@ ("uint", index)) self.codewriter.store(valuetype, valuevar, tmpvar) else: - self.codewriter.comment("***Skipping operation setfield()***") + self._skipped(op) def getarrayitem(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) @@ -479,7 +483,7 @@ ("uint", 1), (indextype, index)) self.codewriter.load(targetvar, targettype, tmpvar) else: - self.codewriter.comment("***Skipping operation getarrayitem()***") + self._skipped(op) def getarraysubstruct(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) @@ -503,7 +507,7 @@ ("uint", 1), (indextype, index)) self.codewriter.store(valuetype, valuevar, tmpvar) else: - self.codewriter.comment("***Skipping operation setarrayitem()***") + self._skipped(op) def getarraysize(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) From cfbolz at codespeak.net Wed Oct 5 13:26:43 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 5 Oct 2005 13:26:43 +0200 (CEST) Subject: [pypy-svn] r18190 - pypy/extradoc/sprintinfo Message-ID: <20051005112643.02D9627B5A@code1.codespeak.net> Author: cfbolz Date: Wed Oct 5 13:26:41 2005 New Revision: 18190 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: added valentino, added michael's dates Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Wed Oct 5 13:26:41 2005 @@ -21,7 +21,7 @@ Anders Chrigstroem 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Holger Krekel 6th-17th Oct flat Lene Wagner 12th-13th Oct flat -Michael Hudson ? flat +Michael Hudson 9/10 - 17/10 flat Carl Friedrich Bolz 7/10? - 16/10 flat Bert Freudenberg 09/10 - 17/10 with Armin Anders Lehmann 09/10 - 14/10 Hotel Porte de Versailles @@ -30,6 +30,7 @@ Andrew Thompson 09/10 - 17/10 Citea Vanves Portes de Versailles Christian Tismer 09/10 - 16/10 Hotel de l'Avenir, 65 rue Madame(+33 1 45 48 84 54) booked a two-bed room, would like to share +Valentino Volonghi 9/10 - 16/10 flat ==================== ============== ===================== People on the following list are likely to come and were From arigo at codespeak.net Wed Oct 5 14:03:25 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 5 Oct 2005 14:03:25 +0200 (CEST) Subject: [pypy-svn] r18192 - in pypy/dist/pypy/translator: backendopt backendopt/test tool Message-ID: <20051005120325.BE98327B57@code1.codespeak.net> Author: arigo Date: Wed Oct 5 14:03:20 2005 New Revision: 18192 Modified: pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/test/test_inline.py pypy/dist/pypy/translator/tool/make_dot.py Log: (pedronis, arigo) Eric pointed out that we can have 'keepalive' as the operation whose exceptions are caught, which makes no sense. As a result, found more bugs in inline, old and new. Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Wed Oct 5 14:03:20 2005 @@ -68,6 +68,7 @@ ops[-4].opname != "setfield" or ops[-3].opname != "cast_pointer" or ops[-2].opname != "getfield" or ops[-1].opname != "cast_pointer" or len(block.exits) != 1 or block.exits[0].args[0] != ops[-2].result or + block.exitswitch is not None or block.exits[0].args[1] != ops[-1].result or not isinstance(ops[-4].args[1], Constant) or ops[-4].args[1].value != "typeptr"): @@ -201,7 +202,6 @@ #try to match the exceptions for simple cases for link in entrymap[graph_to_inline.exceptblock]: copiedblock = copied_blocks[link.prevblock] - copiedblock.operations += generate_keepalive(passon_vars[link.prevblock]) copiedlink = copiedblock.exits[0] eclass = _find_exception_type(copiedblock) #print copiedblock.operations @@ -211,6 +211,8 @@ evalue = copiedlink.args[1] for exceptionlink in afterblock.exits[1:]: if exc_match.value(eclass, exceptionlink.llexitcase): + copiedblock.operations += generate_keepalive( + passon_vars[link.prevblock]) copiedlink.target = exceptionlink.target linkargs = find_args_in_exceptional_case(exceptionlink, link.prevblock, @@ -249,13 +251,18 @@ blocks[-1].exits = blocks[-1].exits[:1] blocks[-1].operations = [] blocks[-1].exitswitch = None + blocks[-1].exits[0].exitcase = None + del blocks[-1].exits[0].llexitcase linkargs = copiedexceptblock.inputargs copiedexceptblock.closeblock(Link(linkargs, blocks[0])) copiedexceptblock.operations += generate_keepalive(linkargs) - afterblock.exits = [afterblock.exits[0]] - afterblock.exitswitch = None + if exception_guarded: + assert afterblock.exits[0].exitcase is None + afterblock.exits = [afterblock.exits[0]] + afterblock.exitswitch = None #cleaning up -- makes sense to be here, because I insert quite #some empty blocks and blocks that can be joined + checkgraph(graph) eliminate_empty_blocks(graph) join_blocks(graph) remove_identical_vars(graph) Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_inline.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_inline.py Wed Oct 5 14:03:20 2005 @@ -1,12 +1,14 @@ import py import os from pypy.objspace.flow.model import traverse, Block, Link, Variable, Constant +from pypy.objspace.flow.model import last_exception, checkgraph from pypy.translator.backendopt.inline import inline_function, CannotInline from pypy.translator.backendopt.inline import auto_inlining from pypy.translator.backendopt.inline import collect_called_functions from pypy.translator.backendopt.inline import measure_median_execution_cost from pypy.translator.translator import Translator from pypy.rpython.llinterp import LLInterpreter +from pypy.rpython.rarithmetic import ovfcheck from pypy.translator.test.snippet import is_perfect_number def no_missing_concretetype(node): @@ -27,19 +29,21 @@ if isinstance(node.last_exc_value, (Variable, Constant)): assert hasattr(node.last_exc_value, 'concretetype') +def sanity_check(t): + # look for missing '.concretetype' + for graph in t.flowgraphs.values(): + checkgraph(graph) + traverse(no_missing_concretetype, graph) + def check_inline(func, in_func, sig): t = Translator(in_func) a = t.annotate(sig) a.simplify() t.specialize() - # look for missing '.concretetype' before inlining (so we don't blame it) - for graph in t.flowgraphs.values(): - traverse(no_missing_concretetype, graph) # inline! + sanity_check(t) # also check before inlining (so we don't blame it) inline_function(t, func, t.flowgraphs[in_func]) - # look for missing '.concretetype' - for graph in t.flowgraphs.values(): - traverse(no_missing_concretetype, graph) + sanity_check(t) interp = LLInterpreter(t.flowgraphs, t.rtyper) return interp @@ -90,7 +94,9 @@ a = t.annotate([int]) a.simplify() t.specialize() + sanity_check(t) # also check before inlining (so we don't blame it) inline_function(t, f, t.flowgraphs[g]) + sanity_check(t) interp = LLInterpreter(t.flowgraphs, t.rtyper) result = interp.eval_function(h, [0]) assert result == 0 @@ -168,6 +174,18 @@ result = interp.eval_function(g, [42]) assert result == 1 +def test_inline_nonraising_into_catching(): + def f(x): + return x+1 + def g(x): + try: + return f(x) + except KeyError: + return 42 + interp = check_inline(f, g, [int]) + result = interp.eval_function(g, [7654]) + assert result == 7655 + def DONOTtest_call_call(): # for reference. Just remove this test if we decide not to support # catching exceptions while inlining a graph that contains further @@ -187,7 +205,9 @@ a = t.annotate([int]) a.simplify() t.specialize() + sanity_check(t) # also check before inlining (so we don't blame it) inline_function(t, f, t.flowgraphs[g]) + sanity_check(t) interp = LLInterpreter(t.flowgraphs, t.rtyper) result = interp.eval_function(g, [100]) assert result == 106 @@ -209,7 +229,9 @@ break else: assert 0, "cannot find ll_rangenext_*() function" + sanity_check(t) # also check before inlining (so we don't blame it) inline_function(t, graph, t.flowgraphs[f]) + sanity_check(t) interp = LLInterpreter(t.flowgraphs, t.rtyper) result = interp.eval_function(f, [10]) assert result == 45 @@ -282,6 +304,22 @@ result = interp.eval_function(f, []) assert result is True +def test_inline_catching_different_exception(): + d = {1: 2} + def f2(n): + try: + return ovfcheck(n+1) + except OverflowError: + raise + def f(n): + try: + return f2(n) + except ValueError: + return -1 + interp = check_inline(f2, f, [int]) + result = interp.eval_function(f, [54]) + assert result == 55 + def test_auto_inline_os_path_isdir(): directory = "./." def f(): Modified: pypy/dist/pypy/translator/tool/make_dot.py ============================================================================== --- pypy/dist/pypy/translator/tool/make_dot.py (original) +++ pypy/dist/pypy/translator/tool/make_dot.py Wed Oct 5 14:03:20 2005 @@ -134,9 +134,11 @@ shape = "box" else: color = "red" - lines.append("exitswitch: %s" % block.exitswitch) shape = "octagon" + if block.exitswitch is not None: + lines.append("exitswitch: %s" % block.exitswitch) + iargs = " ".join(map(repr, block.inputargs)) if block.exc_handler: eh = 'EH' @@ -164,16 +166,14 @@ self.emit_node(name, label=data, shape=shape, color=color, style="filled", fillcolor=fillcolor) # do links/exits - if numblocks == 1: - name2 = self.blockname(block.exits[0].target) - label = " ".join(map(repr, block.exits[0].args)) - self.emit_edge(name, name2, label, style="solid") - elif numblocks >1: - for link in block.exits: - name2 = self.blockname(link.target) - label = " ".join(map(repr, link.args)) + for link in block.exits: + name2 = self.blockname(link.target) + label = " ".join(map(repr, link.args)) + if link.exitcase is not None: label = "%s: %s" %(link.exitcase, label) - self.emit_edge(name, name2, label, style="dotted", color=color) + self.emit_edge(name, name2, label, style="dotted", color="red") + else: + self.emit_edge(name, name2, label, style="solid") def make_dot(graphname, graph, storedir=None, target='ps'): From ac at codespeak.net Wed Oct 5 14:37:41 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 5 Oct 2005 14:37:41 +0200 (CEST) Subject: [pypy-svn] r18195 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20051005123741.91DDC27B58@code1.codespeak.net> Author: ac Date: Wed Oct 5 14:37:41 2005 New Revision: 18195 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_descrtut.py Log: Adjust test to match implemetation differneces. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_descrtut.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_descrtut.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_descrtut.py Wed Oct 5 14:37:41 2005 @@ -20,10 +20,11 @@ try: return dict.__getitem__(self, key) except KeyError: + if key == '__builtins__': raise return self.default def get(self, key, *args): - if not args: + if not args and key != '__builtins__': args = (self.default,) return dict.get(self, key, *args) @@ -174,14 +175,47 @@ Instead, you can get the same information from the list type: - >>> '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 + >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted + ['__add__', + '__class__', + '__contains__', + '__delattr__', + '__delitem__', + '__doc__', + '__eq__', + '__ge__', + '__getattribute__', + '__getitem__', + '__gt__', + '__hash__', + '__iadd__', + '__imul__', + '__init__', + '__iter__', + '__le__', + '__len__', + '__lt__', + '__mul__', + '__ne__', + '__new__', + '__radd__', + '__reduce__', + '__reduce_ex__', + '__repr__', + '__reversed__', + '__rmul__', + '__setattr__', + '__setitem__', + '__str__', + 'append', + 'count', + 'extend', + 'index', + 'insert', + 'pop', + 'remove', + 'reverse', + 'sort'] 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 ac at codespeak.net Wed Oct 5 15:09:58 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 5 Oct 2005 15:09:58 +0200 (CEST) Subject: [pypy-svn] r18197 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20051005130958.4817927B57@code1.codespeak.net> Author: ac Date: Wed Oct 5 15:09:58 2005 New Revision: 18197 Modified: pypy/dist/lib-python/modified-2.4.1/test/mapping_tests.py pypy/dist/lib-python/modified-2.4.1/test/test_dict.py Log: Do not rely on __eq__ allways being used when comparing mappings. Modified: pypy/dist/lib-python/modified-2.4.1/test/mapping_tests.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/mapping_tests.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/mapping_tests.py Wed Oct 5 15:09:58 2005 @@ -640,7 +640,7 @@ class Exc(Exception): pass class BadCmp(object): - def __eq__(self, other): + def __cmp__(self, other): raise Exc() d1 = self._full_mapping({BadCmp(): 1}) Modified: pypy/dist/lib-python/modified-2.4.1/test/test_dict.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_dict.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_dict.py Wed Oct 5 15:09:58 2005 @@ -383,7 +383,7 @@ class Exc(Exception): pass class BadCmp(object): - def __eq__(self, other): + def __cmp__(self, other): raise Exc() d1 = {BadCmp(): 1} From arigo at codespeak.net Wed Oct 5 15:19:26 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 5 Oct 2005 15:19:26 +0200 (CEST) Subject: [pypy-svn] r18199 - pypy/dist/pypy/objspace/flow Message-ID: <20051005131926.6B35A27B57@code1.codespeak.net> Author: arigo Date: Wed Oct 5 15:19:23 2005 New Revision: 18199 Modified: pypy/dist/pypy/objspace/flow/model.py Log: Trying to enforce this condition on the flow model. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Wed Oct 5 15:19:23 2005 @@ -492,6 +492,11 @@ assert block.exits[0].exitcase is None elif block.exitswitch == Constant(last_exception): assert len(block.operations) >= 1 + # check if an exception catch is done on a reasonable + # operation + assert block.operations[-1].opname not in ("keepalive", + "cast_pointer", + "same_as") assert len(block.exits) >= 2 assert block.exits[0].exitcase is None for link in block.exits[1:]: From arigo at codespeak.net Wed Oct 5 15:20:24 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 5 Oct 2005 15:20:24 +0200 (CEST) Subject: [pypy-svn] r18200 - in pypy/dist/pypy: interpreter module/thread module/thread/test module/time Message-ID: <20051005132024.275CA27B57@code1.codespeak.net> Author: arigo Date: Wed Oct 5 15:20:13 2005 New Revision: 18200 Modified: pypy/dist/pypy/interpreter/miscutils.py pypy/dist/pypy/module/thread/gil.py pypy/dist/pypy/module/thread/test/support.py pypy/dist/pypy/module/thread/test/test_local.py pypy/dist/pypy/module/time/interp_time.py Log: Hackish pseudo-solution to release the GIL around a call to time.sleep(). Simplifies testing too. Modified: pypy/dist/pypy/interpreter/miscutils.py ============================================================================== --- pypy/dist/pypy/interpreter/miscutils.py (original) +++ pypy/dist/pypy/interpreter/miscutils.py Wed Oct 5 15:20:13 2005 @@ -145,3 +145,6 @@ def yield_thread(self): """Called from time to time between the interpretation of bytecodes. Hook for threading models that require it.""" + + def getGIL(self): + return None # XXX temporary hack! Modified: pypy/dist/pypy/module/thread/gil.py ============================================================================== --- pypy/dist/pypy/module/thread/gil.py (original) +++ pypy/dist/pypy/module/thread/gil.py Wed Oct 5 15:20:13 2005 @@ -35,3 +35,6 @@ GIL.release() # Other threads can run here GIL.acquire(True) + + def getGIL(self): + return self.GIL # XXX temporary hack! 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 Oct 5 15:20:13 2005 @@ -1,33 +1,54 @@ import py +import time, gc from pypy.conftest import gettestobjspace +from pypy.interpreter.gateway import ObjSpace, W_Root, interp2app_temp + + +def waitfor(space, w_condition, timeout=10.0): + w_sleep = space.appexec([], "():\n import time; return time.sleep") + limit = time.time() + timeout + while time.time() <= limit: + space.call_function(w_sleep, space.wrap(0.04)) + gc.collect() + if space.is_true(space.call_function(w_condition)): + return + print '*** timed out ***' +waitfor.unwrap_spec = [ObjSpace, W_Root, float] + class GenericTestThread: def setup_class(cls): - space = gettestobjspace(usemodules=('thread',)) + space = gettestobjspace(usemodules=('thread', 'time')) cls.space = space - cls.w_waitfor = space.appexec([], """(): - import time - def waitfor(expr, timeout=10.0): - limit = time.time() + timeout - while time.time() <= limit: - time.sleep(0.002) - if expr(): - return - print '*** timed out ***' - return waitfor - """) + cls.w_waitfor = space.wrap(interp2app_temp(waitfor)) cls.w_busywait = space.appexec([], """(): import time - def busywait(t): - limit = time.time() + t - while time.time() <= limit: - time.sleep(0.002) - return busywait + return time.sleep """) - space.appexec([], """(): - import sys - sys.setcheckinterval(1) - """) +## cls.w_waitfor = space.appexec([], """(): +## import time +## def waitfor(expr, timeout=10.0): +## limit = time.time() + timeout +## while time.time() <= limit: +## time.sleep(0.002) +## 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.002) +## return busywait +## """) + +## space.appexec([], """(): +## import sys +## sys.setcheckinterval(1) +## """) 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 Wed Oct 5 15:20:13 2005 @@ -3,7 +3,7 @@ class AppTestLocal(GenericTestThread): - def test_local(self): + def test_local_1(self): import thread from thread import _local as tlsobject freed = [] 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 Wed Oct 5 15:20:13 2005 @@ -1,4 +1,6 @@ import time +from pypy.interpreter.gateway import ObjSpace + def clock(space): return space.wrap(time.clock()) @@ -6,6 +8,11 @@ def time_(space): return space.wrap(time.time()) -def sleep(seconds): +def sleep(space, seconds): + # XXX Temporary hack: we need to make sure the GIL is released while + # sleeping. XXX should be done differently !!! + GIL = space.threadlocals.getGIL() + if GIL is not None: GIL.release() time.sleep(seconds) -sleep.unwrap_spec = [float] + if GIL is not None: GIL.acquire(True) +sleep.unwrap_spec = [ObjSpace, float] From ac at codespeak.net Wed Oct 5 18:17:59 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 5 Oct 2005 18:17:59 +0200 (CEST) Subject: [pypy-svn] r18202 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20051005161759.81D7E27B56@code1.codespeak.net> Author: ac Date: Wed Oct 5 18:17:58 2005 New Revision: 18202 Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Log: Minor optimization. Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Wed Oct 5 18:17:58 2005 @@ -135,6 +135,12 @@ return 1 return 0 +def is_constant_true(space, node): + if isinstance(node, ast.Const): + if space.is_true(node.value): + return 1 + return 0 + class CodeGenerator(ast.ASTVisitor): """Defines basic code generator for Python bytecode """ @@ -428,11 +434,14 @@ self.setups.append((LOOP, loop)) self.set_lineno(node, force=True) - node.test.accept( self ) - self.emitop_block('JUMP_IF_FALSE', else_ or after) + if is_constant_true(self.space, node.test): + self.nextBlock() + else: + node.test.accept( self ) + self.emitop_block('JUMP_IF_FALSE', else_ or after) - self.nextBlock() - self.emit('POP_TOP') + self.nextBlock() + self.emit('POP_TOP') node.body.accept( self ) self.emitop_block('JUMP_ABSOLUTE', loop) From ac at codespeak.net Wed Oct 5 19:20:07 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 5 Oct 2005 19:20:07 +0200 (CEST) Subject: [pypy-svn] r18203 - pypy/dist/pypy/interpreter Message-ID: <20051005172007.9D78C27B55@code1.codespeak.net> Author: ac Date: Wed Oct 5 19:20:07 2005 New Revision: 18203 Modified: pypy/dist/pypy/interpreter/executioncontext.py pypy/dist/pypy/interpreter/pyframe.py Log: Trace jumping backwards in the same line. Modified: pypy/dist/pypy/interpreter/executioncontext.py ============================================================================== --- pypy/dist/pypy/interpreter/executioncontext.py (original) +++ pypy/dist/pypy/interpreter/executioncontext.py Wed Oct 5 19:20:07 2005 @@ -72,42 +72,46 @@ return code = getattr(frame, 'pycode') if frame.instr_lb <= frame.last_instr < frame.instr_ub: - return - - size = len(code.co_lnotab) / 2 - addr = 0 - line = code.co_firstlineno - p = 0 - lineno = code.co_lnotab - while size > 0: - c = ord(lineno[p]) - if (addr + c) > frame.last_instr: - break - addr += c - if c: - frame.instr_lb = addr - - line += ord(lineno[p + 1]) - p += 2 - size -= 1 - - if addr == frame.last_instr: - frame.f_lineno = line - self._trace(frame, 'line', self.space.w_None) - - if size > 0: - while True: - size -= 1 - if size < 0: - break - addr += ord(lineno[p]) - if ord(lineno[p + 1]): + if frame.last_instr <= frame.instr_prev: + # We jumped backwards in the same line. + self._trace(frame, 'line', self.space.w_None) + else: + size = len(code.co_lnotab) / 2 + addr = 0 + line = code.co_firstlineno + p = 0 + lineno = code.co_lnotab + while size > 0: + c = ord(lineno[p]) + if (addr + c) > frame.last_instr: break + addr += c + if c: + frame.instr_lb = addr + + line += ord(lineno[p + 1]) p += 2 - frame.instr_ub = addr - else: - frame.instr_ub = sys.maxint + size -= 1 + + if size > 0: + while True: + size -= 1 + if size < 0: + break + addr += ord(lineno[p]) + if ord(lineno[p + 1]): + break + p += 2 + frame.instr_ub = addr + else: + frame.instr_ub = sys.maxint + + if frame.instr_lb == frame.last_instr: # At start of line! + frame.f_lineno = line + self._trace(frame, 'line', self.space.w_None) + frame.instr_prev = frame.last_instr + def exception_trace(self, frame, operationerr): "Trace function called upon OperationError." operationerr.record_interpreter_traceback() Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Wed Oct 5 19:20:07 2005 @@ -62,7 +62,8 @@ # For tracing self.instr_lb = 0 self.instr_ub = -1 - + self.instr_prev = -1; + def hide(self): return self.pycode.hidden_applevel From pedronis at codespeak.net Wed Oct 5 19:56:23 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 5 Oct 2005 19:56:23 +0200 (CEST) Subject: [pypy-svn] r18204 - in pypy/dist/pypy/translator: . test Message-ID: <20051005175623.973E727B53@code1.codespeak.net> Author: pedronis Date: Wed Oct 5 19:56:22 2005 New Revision: 18204 Modified: pypy/dist/pypy/translator/simplify.py pypy/dist/pypy/translator/test/test_simplify.py Log: keepalive removal if the kept alive variable is only used in dead ops too Modified: pypy/dist/pypy/translator/simplify.py ============================================================================== --- pypy/dist/pypy/translator/simplify.py (original) +++ pypy/dist/pypy/translator/simplify.py Wed Oct 5 19:56:22 2005 @@ -413,7 +413,7 @@ pos neg nonzero abs hex oct ord invert add sub mul truediv floordiv div mod divmod pow lshift rshift and_ or_ xor int float long lt le eq ne gt ge cmp coerce contains - iter get same_as cast_pointer getfield '''.split(): + iter get same_as cast_pointer getfield getarrayitem getsubstruct'''.split(): CanRemove[_op] = True del _op CanRemoveBuiltins = { @@ -427,6 +427,10 @@ read_vars = {} # set of variables really used variable_flow = {} # map {Var: list-of-Vars-it-depends-on} + transport_flow = {} # map {Var: list-of-Vars-depending-on-it-through-links-or-indentity-ops} + + keepalive_vars = {} # set of variables in keepalives + def canremove(op, block): if op.opname not in CanRemove: return False @@ -439,7 +443,9 @@ for block in blocks: # figure out which variables are ever read for op in block.operations: - if not canremove(op, block): # mark the inputs as really needed + if op.opname == 'keepalive': + keepalive_vars[op.args[0]] = True + elif not canremove(op, block): # mark the inputs as really needed for arg in op.args: read_vars[arg] = True else: @@ -447,6 +453,8 @@ # on the input variables deps = variable_flow.setdefault(op.result, []) deps.extend(op.args) + if op.opname in ('cast_pointer', 'same_as'): + transport_flow.setdefault(op.args[0], []).append(op.result) if isinstance(block.exitswitch, Variable): read_vars[block.exitswitch] = True @@ -461,6 +469,7 @@ for arg, targetarg in zip(link.args, link.target.inputargs): deps = variable_flow.setdefault(targetarg, []) deps.append(arg) + transport_flow.setdefault(arg, []).append(targetarg) else: # return and except blocks implicitely use their input variable(s) for arg in block.inputargs: @@ -473,12 +482,40 @@ # flow read_vars backwards so that any variable on which a read_vars # depends is also included in read_vars - pending = list(read_vars) + def flow_read_var_backward(pending): + pending = list(pending) + for var in pending: + for prevvar in variable_flow.get(var, []): + if prevvar not in read_vars: + read_vars[prevvar] = True + pending.append(prevvar) + + flow_read_var_backward(read_vars) + + # compute vars depending on a read-var through the transport-flow + read_var_aliases = {} + pending = [] + for var in transport_flow: + if var in read_vars: + pending.append(var) + read_var_aliases[var] = True for var in pending: - for prevvar in variable_flow.get(var, []): - if prevvar not in read_vars: - read_vars[prevvar] = True - pending.append(prevvar) + for nextvar in transport_flow.get(var, []): + if nextvar not in read_var_aliases: + read_var_aliases[nextvar] = True + pending.append(nextvar) + + # a keepalive var is read-var if it's an alias reached from some read-var + # through the transport flow + new_read_vars = {} + for var in keepalive_vars: + if var in read_var_aliases: + read_vars[var] = True + new_read_vars[var] = True + + # flow backward the new read-vars + flow_read_var_backward(new_read_vars) + for block in blocks: @@ -488,6 +525,9 @@ if op.result not in read_vars: if canremove(op, block): del block.operations[i] + elif op.opname == 'keepalive': + if op.args[0] not in read_vars: + del block.operations[i] elif op.opname == 'simple_call': # XXX we want to have a more effective and safe # way to check if this operation has side effects Modified: pypy/dist/pypy/translator/test/test_simplify.py ============================================================================== --- pypy/dist/pypy/translator/test/test_simplify.py (original) +++ pypy/dist/pypy/translator/test/test_simplify.py Wed Oct 5 19:56:22 2005 @@ -57,3 +57,38 @@ t.backend_optimizations() assert t.flowgraphs[g].startblock.operations[-1].opname == 'direct_call' + +def test_remove_pointless_keepalive(): + from pypy.rpython import objectmodel + class C: + y = None + z1 = None + z2 = None + + def g(): + return C() + + def f(i): + c = g() + c.y + if i: + n = c.z1 + else: + n = c.z2 + objectmodel.keepalive_until_here(c, n) + + t = Translator(f) + a = t.annotate([int]) + t.specialize() + t.backend_optimizations() + + #t.view() + + graph = t.flowgraphs[f] + + for block in graph.iterblocks(): + for op in block.operations: + assert op.opname != 'getfield' + if op.opname == 'keepalive': + assert op.args[0] in graph.getargs() + From arigo at codespeak.net Wed Oct 5 20:12:51 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 5 Oct 2005 20:12:51 +0200 (CEST) Subject: [pypy-svn] r18205 - pypy/extradoc/sprintinfo Message-ID: <20051005181251.54AC227B55@code1.codespeak.net> Author: arigo Date: Wed Oct 5 20:12:49 2005 New Revision: 18205 Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt Log: Hotel info. I could only get a single-person room, so let's try to somehow map the three persons to this and Christian's two-beds room... Modified: pypy/extradoc/sprintinfo/paris-2005-people.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-people.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-people.txt Wed Oct 5 20:12:49 2005 @@ -16,20 +16,19 @@ Jacob Hallen 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Laura Creighton 8/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Beatrice Duering 9/10 - 17/10 flat -Armin Rigo 8/10 - 17/10 booking... +Armin Rigo 8/10 - 17/10 Hotel de l'Avenir, 65 rue Madame(+33 1 45 48 84 54) Samuele Pedroni 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Anders Chrigstroem 9/10 - 17/10 Hotel Lenox, 15 Rue Delambre(+33 1 43353450) Holger Krekel 6th-17th Oct flat Lene Wagner 12th-13th Oct flat Michael Hudson 9/10 - 17/10 flat Carl Friedrich Bolz 7/10? - 16/10 flat -Bert Freudenberg 09/10 - 17/10 with Armin +Bert Freudenberg 09/10 - 17/10 Hotel de l'Avenir, 65 rue Madame(+33 1 45 48 84 54) Anders Lehmann 09/10 - 14/10 Hotel Porte de Versailles Boris Feigin 09/10 - 16/10 hotel Amaury Forgeot d'Arc 10/10 - 16/10 Private Andrew Thompson 09/10 - 17/10 Citea Vanves Portes de Versailles Christian Tismer 09/10 - 16/10 Hotel de l'Avenir, 65 rue Madame(+33 1 45 48 84 54) - booked a two-bed room, would like to share Valentino Volonghi 9/10 - 16/10 flat ==================== ============== ===================== From arigo at codespeak.net Wed Oct 5 20:42:07 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 5 Oct 2005 20:42:07 +0200 (CEST) Subject: [pypy-svn] r18206 - pypy/dist/pypy/doc Message-ID: <20051005184207.DEC7D27B54@code1.codespeak.net> Author: arigo Date: Wed Oct 5 20:42:06 2005 New Revision: 18206 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Started section on classes and instances. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Wed Oct 5 20:42:06 2005 @@ -610,6 +610,8 @@ called the "auxiliary variable" which we will use in particular cases (which we omit from the notation when it is irrelevant). +.. _`definition of V`: + Let us assume that we are given a user program, which for the purpose of the model we assume to be fully known in advance. Let us define the set *V* of all variables as follows: @@ -1000,6 +1002,78 @@ As with `merge_into`_, it identifies the two lists. +Classes and instances +~~~~~~~~~~~~~~~~~~~~~ + +Remember that Python has no notion of classes declaring attributes and +methods. Classes are merely hierarchical namespaces: an expression like +``obj.attr`` means that the ``attr`` attribute is looked up in the class +that ``obj`` is an instance of at run-time, and all parent classes (a +``getattr`` operation). Expressions like ``obj.meth()`` that look like +method calls are actually grouped as ``(obj.meth)()``: they correspond +to two operations, a ``getattr`` followed by a ``call``. The +intermediate object ``obj.meth`` is a bound method. + +As the goal of annotator is to derive type information about the user +program that is static enough, it must reconstruct a static structure +for each class in the hierarchy. It does so by observing the usage +patterns of the classes and their instances, by propagating annotations +of the form ``SomeInstance(cls)`` -- which stands for "an instance of +the class *cls* or any subclass". Instance fields are attached to a +class whenever we see that the field is being written to an instance of +this class. If the user program manipulates instances polymorphically, +the variables holding the instances will be annotated +``SomeInstance(cls)`` with some abstract base class *cls*; accessing +attributes on such generalized instances lifts the inferred attribute +declarations up to *cls*. The same technique works for inferring the +location of both fields and methods. + +~~~~~~~~~~~~~~~~~~~~~~ + +We assume that the classes in the user program are organized in a single +inheritance tree rooted at the ``object`` base class. (Python supports +multiple inheritance, but the annotator is limited to single inheritance +plus simple mix-ins.) We also assume that polymorphic instance usage is +"bounded" in the sense that all instances that can reach a specific +program point are instances of a user-defined common base class, i.e. +not ``object``. + +We recall from `definition of V`_ that we have a variable ``v_C.attr`` +for each class ``C`` and each possible attribute name ``attr``. The +annotation state *(b,E)* has the following meaning on these variables: + +* the binding map *b* gives an annotation to each of them, as with other + variables. The annotation ``b(v_C.attr)`` is the inferred type of the + values that can show up when the attribute ``attr`` is read out of an + instance of ``C``. + +* to account for the inheritance between classes, the equivalence + relation *E* identifies some of these variables as follows: if an + attribute ``attr`` is found to belong to a base class ``C``, then all + variables ``v_D.attr`` for all subclasses ``D`` of ``C`` are + identified with ``v_C.attr``. This ensures that the instances of the + subclasses are all given the same generic attribute defined in ``C``. + +Formally:: + + z=getattr(x,attr) | z', b(x)=Inst(C) + --------------------------------------------------------------------- + E' = E union (v_C.attr ~ v_D.attr) for all D subclass of C + E' = E union (z' ~ v_C.attr) + b' = b with (z->lookup_filter(b(z'), C)) + + + setattr(x,attr,z), b(x)=Inst(C) + --------------------------------------------------------------------- + E' = E union (v_C.attr ~ v_D.attr) for all D subclass of C + merge_into(z, v_C.attr) + +Note the similarity with the lists' ``getitem`` and ``setitem``, in +particular the usage of the auxiliary variable *z'*. + +XXX + + Draft ~~~~~ @@ -1092,27 +1166,6 @@ XXX constant arguments to operations -Classes and instances -~~~~~~~~~~~~~~~~~~~~~ - -We assume that the classes in the user program are organized in a single -inheritance tree rooted at the ``object`` base class. (Python supports -multiple inheritance, but the annotator is limited to single inheritance -plus simple mix-ins.) - -Remember that Python has no notion of classes declaring attributes and -methods. Classes are merely hierarchical namespaces: an expression like -``obj.attr`` means that the ``attr`` attribute is looked up in the class -that ``obj`` is an instance of at run-time, and all parent classes (a -``getattr`` operation). Expressions like ``obj.meth()`` that look like -method calls are actually grouped as ``(obj.meth)()``: they correspond -to two operations, a ``getattr`` followed by a ``call``. - -So it is down to the annotator to reconstruct a static structure for -each class in the hierarchy XXX. - -XXX - Termination ~~~~~~~~~~~ From pedronis at codespeak.net Wed Oct 5 23:33:06 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 5 Oct 2005 23:33:06 +0200 (CEST) Subject: [pypy-svn] r18207 - pypy/extradoc/sprintinfo Message-ID: <20051005213306.1D5DE27B54@code1.codespeak.net> Author: pedronis Date: Wed Oct 5 23:33:03 2005 New Revision: 18207 Added: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (contents, props changed) Log: (arigo, pedronis) lists of possible tasks for the Paris sprint. Not really a subset or superset of what will happen at the sprint Added: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Wed Oct 5 23:33:03 2005 @@ -0,0 +1,64 @@ + +RTyper tasks +------------- + +- fixed size lists +- poor-man type erasure for rlist and rdict + +- rtyping of classes/instances/methods for target languages with direct/prevalent OO/class support: + devise a low-level model variation for this case + +Annotator related tasks +------------------------ + +- support the notion of separate/external functions (and classes/PBCs) + in preparation for separate compilations + +JIT work related +----------------- +- an ll interpreter written in RPython +- Saving ll graphs plus a loader written in RPython + +- Start thinking/experimenting with JIT generation at translation time + +- start a genasm back-end + +Threading/concurrency +---------------------- + +- release the GIL around system calls +- understand and possibly fix where the overhead, when threads are enabled, comes from + +- generating (single-threaded) stackless C code + +Implementation/translation +--------------------------- + +- stack overflow detection (needed to be able to run many compliancy tests) +- try more interp. level optimisations (dicts with string keys, more agressive use of fastcall*...) + +- (socket module, PEP302) + +GC related tasks +----------------- + +- look into implementing weakrefs +- (improve refcounting) +- (passes toward integrating other GCs, rpython/memory) + + +Refactorings/cleanups +---------------------- + +- cbuild/translator.Translator (use SCons?) +- PyPy option handling unification, passing py.py options to targetpypy* +- inline (transforms in general) + +- genc: producing multiple .h/.c files tracking Python code origin + +Larger whole projects +---------------------- + +- Javascript frontend +- support for developing C extensions for CPython with RPython code + From pedronis at codespeak.net Thu Oct 6 11:53:22 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 6 Oct 2005 11:53:22 +0200 (CEST) Subject: [pypy-svn] r18209 - pypy/extradoc/sprintinfo Message-ID: <20051006095322.5898027B58@code1.codespeak.net> Author: pedronis Date: Thu Oct 6 11:53:20 2005 New Revision: 18209 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: order type, clarification Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Thu Oct 6 11:53:20 2005 @@ -14,7 +14,7 @@ - support the notion of separate/external functions (and classes/PBCs) in preparation for separate compilations -JIT work related +JIT related work ----------------- - an ll interpreter written in RPython - Saving ll graphs plus a loader written in RPython @@ -50,7 +50,7 @@ Refactorings/cleanups ---------------------- -- cbuild/translator.Translator (use SCons?) +- cbuild/translator.Translator (use SCons?, use/generalize TranslationDriver) - PyPy option handling unification, passing py.py options to targetpypy* - inline (transforms in general) From pedronis at codespeak.net Thu Oct 6 13:14:32 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 6 Oct 2005 13:14:32 +0200 (CEST) Subject: [pypy-svn] r18211 - pypy/extradoc/sprintinfo Message-ID: <20051006111432.2EB3527B58@code1.codespeak.net> Author: pedronis Date: Thu Oct 6 13:14:30 2005 New Revision: 18211 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: some missed things Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Thu Oct 6 13:14:30 2005 @@ -37,6 +37,9 @@ - stack overflow detection (needed to be able to run many compliancy tests) - try more interp. level optimisations (dicts with string keys, more agressive use of fastcall*...) +- compute correct max stack size in compiler (?) +- cleanup our multiple compiler situation (if not already done before the sprint) + - (socket module, PEP302) GC related tasks From tismer at codespeak.net Thu Oct 6 14:14:07 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 6 Oct 2005 14:14:07 +0200 (CEST) Subject: [pypy-svn] r18213 - pypy/dist/pypy/translator/tool Message-ID: <20051006121407.11C1427B5C@code1.codespeak.net> Author: tismer Date: Thu Oct 6 14:14:06 2005 New Revision: 18213 Modified: pypy/dist/pypy/translator/tool/cbuild.py Log: making a test correct, although it is disabled... Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Thu Oct 6 14:14:06 2005 @@ -296,7 +296,7 @@ cfname = str(cfile) cfile = cfile.open('w') cfile.write(""" -#include +#include int main() { return 0; From arigo at codespeak.net Thu Oct 6 14:14:40 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 14:14:40 +0200 (CEST) Subject: [pypy-svn] r18214 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051006121440.C088B27B5C@code1.codespeak.net> Author: arigo Date: Thu Oct 6 14:14:39 2005 New Revision: 18214 Modified: pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/src/mem.h Log: Don't use the GC_all_interior_pointers flag (crashes on Windows for initialization-order-related issues). Use the equivalent way of always mallocing with IGNORE_OFF_PAGE. For reference, the GC_MALLOC macro variants: ATOMIC means "don't search in the object for further pointer". non-ATOMIC means "search in the complete object for further pointer". Normally, if there is anywhere in memory a pointer-looking number that appears to point to any of the allocated bytes of an object, the object is kept alive. IGNORE_OFF_PAGE means "ignore pointer-looking numbers that point inside the object but too far away from the start of the object". Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Thu Oct 6 14:14:39 2005 @@ -363,7 +363,6 @@ yield '#define USING_BOEHM_GC' def gc_startup_code(self): - yield 'GC_all_interior_pointers = 0;' yield 'GC_INIT();' 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 Thu Oct 6 14:14:39 2005 @@ -49,12 +49,10 @@ #ifdef USING_BOEHM_GC -#define BOEHM_MALLOC_0_0 GC_MALLOC -#define BOEHM_MALLOC_1_0 GC_MALLOC_ATOMIC -#define BOEHM_MALLOC_0_1 GC_MALLOC -#define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC -/* #define BOEHM_MALLOC_0_1 GC_MALLOC_IGNORE_OFF_PAGE */ -/* #define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE */ +#define BOEHM_MALLOC_0_0 GC_MALLOC_IGNORE_OFF_PAGE +#define BOEHM_MALLOC_1_0 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE +#define BOEHM_MALLOC_0_1 GC_MALLOC_IGNORE_OFF_PAGE +#define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE #define OP_BOEHM_ZERO_MALLOC(size, r, is_atomic, is_varsize, err) { \ r = (void*) BOEHM_MALLOC_ ## is_atomic ## _ ## is_varsize (size); \ From ac at codespeak.net Thu Oct 6 16:01:58 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Thu, 6 Oct 2005 16:01:58 +0200 (CEST) Subject: [pypy-svn] r18215 - in pypy/dist/pypy: . interpreter interpreter/astcompiler interpreter/pyparser/test interpreter/stablecompiler interpreter/test lib/_stablecompiler lib/test2 module/parser objspace/std tool translator Message-ID: <20051006140158.6979D27B53@code1.codespeak.net> Author: ac Date: Thu Oct 6 16:01:57 2005 New Revision: 18215 Removed: pypy/dist/pypy/interpreter/stablecompiler/ pypy/dist/pypy/lib/_stablecompiler/ pypy/dist/pypy/lib/test2/test_stablecompiler.py pypy/dist/pypy/module/parser/ Modified: pypy/dist/pypy/conftest.py pypy/dist/pypy/interpreter/astcompiler/transformer.py pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py pypy/dist/pypy/interpreter/pyparser/test/test_samples.py pypy/dist/pypy/interpreter/test/test_compiler.py pypy/dist/pypy/interpreter/test/test_interpreter.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/tool/option.py pypy/dist/pypy/translator/ann_override.py Log: Cleaning up our compilers. Modified: pypy/dist/pypy/conftest.py ============================================================================== --- pypy/dist/pypy/conftest.py (original) +++ pypy/dist/pypy/conftest.py Thu Oct 6 16:01:57 2005 @@ -37,7 +37,7 @@ callback=usemodules_callback, default=[], help="(mixed) modules to use."), Option('--compiler', action="store", type="string", dest="compiler", - metavar="[stable|_stable|ast|cpython]", default='ast', + metavar="[ast|cpython]", default='ast', help="""select compiling approach. see pypy/doc/README.compiling""") ) Modified: pypy/dist/pypy/interpreter/astcompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/transformer.py Thu Oct 6 16:01:57 2005 @@ -29,7 +29,6 @@ # make sure we import the parser with the correct grammar import pypy.interpreter.pyparser.pythonparse -from pypy.interpreter.stablecompiler.ast import * import parser import pypy.interpreter.pyparser.pysymbol as symbol import pypy.interpreter.pyparser.pytoken as token Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Oct 6 16:01:57 2005 @@ -2,7 +2,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.argument import Arguments 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 from pypy.rpython.rarithmetic import r_uint, intmask @@ -331,10 +330,7 @@ try: return self.default_compiler except AttributeError: - if (self.options.compiler == 'stable' or - self.options.compiler == '_stable'): - compiler = PythonCompiler(self) - elif self.options.compiler == 'cpython': + if self.options.compiler == 'cpython': compiler = CPythonCompiler(self) elif self.options.compiler == 'ast': compiler = PythonAstCompiler(self) Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Thu Oct 6 16:01:57 2005 @@ -187,203 +187,6 @@ ######## -class PythonCompiler(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 scratch - the whole source after having only added a new '\n') - """ - def compile(self, source, filename, mode, flags): - from pyparser.error import SyntaxError - from pyparser.pythonutil import internal_pypy_parse - flags |= __future__.generators.compiler_flag # always on (2.2 compat) - # XXX use 'flags' - space = self.space - try: - parse_result = internal_pypy_parse(source, mode, True, flags, space) - except SyntaxError, e: - 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): - """NOT_RPYTHON""" - from pyparser.pythonutil import parse_result_to_nested_tuples - # the result of this conversion has no useful type in RPython - tuples = parse_result_to_nested_tuples(parse_result, True) - - # __________ - # XXX this uses the non-annotatable stablecompiler at interp-level - from pypy.interpreter import stablecompiler - from pypy.interpreter.stablecompiler.pycodegen import ModuleCodeGenerator - from pypy.interpreter.stablecompiler.pycodegen import InteractiveCodeGenerator - from pypy.interpreter.stablecompiler.pycodegen import ExpressionCodeGenerator - from pypy.interpreter.stablecompiler.transformer import Transformer - space = self.space - try: - transformer = Transformer(filename) - tree = transformer.compile_node(tuples) - stablecompiler.misc.set_filename(filename, tree) - flag_names = get_flag_names(space, flags) - if mode == 'exec': - codegenerator = ModuleCodeGenerator(tree, flag_names) - elif mode == 'single': - codegenerator = InteractiveCodeGenerator(tree, flag_names) - else: # mode == 'eval': - codegenerator = ExpressionCodeGenerator(tree, flag_names) - 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 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: - 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 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.""" - - def __init__(self, space): - from pypy.interpreter.error import debug_print - PythonCompiler.__init__(self, space) - debug_print("importing the 'compiler' package at app-level...", - newline=False) - 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 - ''') - self.w_compilefake = self.space.appexec([], r'''(): - 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): - import os - if os.path.exists('fakecompiler.py') and mode != 'single': - self.printmessage("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, 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 - # while translating PyPy, we can cheat here. The annotator - # doesn't see this because it thinks that we_are_translated() - # returns True. - return PythonCompiler.compile_parse_result(self, parse_result, - filename, mode, flags) - source_encoding, stack_element = parse_result - 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: - from pypy.interpreter.pyparser import pysymbol - w_nested_tuples = space.newtuple([ - space.wrap(pysymbol.encoding_decl), - w_nested_tuples, - space.wrap(source_encoding)]) - - w_code = space.call_function(self._get_compiler(mode), - w_nested_tuples, - space.wrap(filename), - space.wrap(mode), - w_flag_names) - 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 - - def fakecompile(self, source, filename, mode, flags): - flags |= __future__.generators.compiler_flag # always on (2.2 compat) - flag_names = get_flag_names(self.space, 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 @@ -433,64 +236,4 @@ raise OperationError(space.w_TypeError,space.wrap(str(e))) assert isinstance(c,PyCode) return c - #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(self.space, 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 - - XXX: WRITEME - """ 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 Oct 6 16:01:57 2005 @@ -3,8 +3,8 @@ 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.stablecompiler.transformer import Transformer -import pypy.interpreter.stablecompiler.ast as stable_ast +from pypy.interpreter.testcompiler.transformer import Transformer +import pypy.interpreter.testcompiler.ast as test_ast import pypy.interpreter.astcompiler.ast as ast_ast import py.test @@ -31,12 +31,12 @@ def nodes_equal(left, right, check_lineno=False): - if not isinstance(left,stable_ast.Node) or not isinstance(right,ast_ast.Node): + if not isinstance(left,test_ast.Node) or not isinstance(right,ast_ast.Node): return left==right if left.__class__.__name__ != right.__class__.__name__: print "Node type mismatch:", left, right return False - if isinstance(left,stable_ast.Function) and isinstance(right,ast_ast.Function): + if isinstance(left,test_ast.Function) and isinstance(right,ast_ast.Function): left_nodes = list(left.getChildren()) right_nodes = list(right.getChildren()) left_args = left_nodes[2] @@ -45,7 +45,7 @@ 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): + elif isinstance(left,test_ast.Lambda) and isinstance(right,ast_ast.Lambda): left_nodes = list(left.getChildren()) right_nodes = list(right.getChildren()) left_args = left_nodes[0] @@ -54,7 +54,7 @@ del right_nodes[0] if not arglist_equal(left_args, right_args): return False - elif isinstance(left,stable_ast.Const): + elif isinstance(left,test_ast.Const): if isinstance(right,ast_ast.Const): r = left.value == right.value elif isinstance(right,ast_ast.NoneConst): @@ -75,7 +75,7 @@ print "(0) (%s) left: %s, right: %s" % (left, left.lineno, right.lineno) return False return True - elif isinstance(right, ast_ast.Return) and isinstance(left, stable_ast.Return): + elif isinstance(right, ast_ast.Return) and isinstance(left, test_ast.Return): left_nodes = left.getChildren() if right.value is None: right_nodes = (ast_ast.Const(None),) 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 Oct 6 16:01:57 2005 @@ -82,7 +82,7 @@ rcode = codegen.getCode() return rcode -def compile_with_stablecompiler(expr, target='exec'): +def compile_with_testcompiler(expr, target='exec'): from pypy.interpreter.testcompiler import compile # from compiler import compile return compile(expr, '', target) @@ -142,7 +142,7 @@ if space is None: space = std_space - sc_code = compile_with_stablecompiler(expr, target=target) + sc_code = compile_with_testcompiler(expr, target=target) ac_code = compile_with_astcompiler(expr, target=target, space=space) compare_code(ac_code, sc_code, space=space) 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 Oct 6 16:01:57 2005 @@ -93,7 +93,7 @@ assert False, testname -from pypy.interpreter.stablecompiler.transformer import Transformer as PyPyTransformer +from pypy.interpreter.testcompiler.transformer import Transformer as PyPyTransformer from compiler.transformer import Transformer as PythonTransformer def _check_tuples_equality(pypy_tuples, python_tuples, testname): 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 Oct 6 16:01:57 2005 @@ -1,7 +1,7 @@ import __future__ import autopath import py -from pypy.interpreter.pycompiler import CPythonCompiler, PythonCompiler, PythonAstCompiler +from pypy.interpreter.pycompiler import CPythonCompiler, PythonAstCompiler from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError from pypy.interpreter.argument import Arguments @@ -323,38 +323,11 @@ def setup_method(self, method): self.compiler = self.space.getexecutioncontext().compiler - def test_globals_warnings(self): - py.test.skip('INPROGRES') - - def test_return_in_generator(self): - py.test.skip('INPROGRES') - - def test_yield_in_finally(self): - py.test.skip('INPROGRES') - - class TestPyCCompiler(BaseTestCompiler): def setup_method(self, method): self.compiler = CPythonCompiler(self.space) -class TestPurePythonCompiler(BaseTestCompiler): - def setup_method(self, method): - self.compiler = PythonCompiler(self.space) - - def test_globals_warnings(self): - py.test.skip('INPROGRES') - - def test_return_in_generator(self): - py.test.skip('INPROGRES') - - def test_yield_in_finally(self): - py.test.skip('INPROGRES') - class TestPythonAstCompiler(BaseTestCompiler): def setup_method(self, method): self.compiler = PythonAstCompiler(self.space) -class SkippedForNowTestPyPyCompiler(BaseTestCompiler): - def setup_method(self, method): - self.compiler = PyPyCompiler(self.space) - Modified: pypy/dist/pypy/interpreter/test/test_interpreter.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_interpreter.py (original) +++ pypy/dist/pypy/interpreter/test/test_interpreter.py Thu Oct 6 16:01:57 2005 @@ -234,7 +234,7 @@ class TestPyPyInterpreter(TestInterpreter): """Runs the previous test with the pypy parser""" - from pypy.interpreter.pycompiler import PythonCompiler as CompilerClass + from pypy.interpreter.pycompiler import PythonAstCompiler as CompilerClass def test_extended_arg(self): py.test.skip("expression too large for the recursive parser") Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Oct 6 16:01:57 2005 @@ -98,12 +98,6 @@ if self.options.uselibfile: self.inituselibfile() - # XXX hack!: patch the compiler after initialization is complete - if self.options.compiler == '_stable': - from pypy.interpreter.pycompiler import PythonCompilerApp - self.default_compiler = PythonCompilerApp(self) - self.getexecutioncontext().compiler = self.default_compiler - if self.options.oldstyle: self.enable_old_style_classes_as_default_metaclass() Modified: pypy/dist/pypy/tool/option.py ============================================================================== --- pypy/dist/pypy/tool/option.py (original) +++ pypy/dist/pypy/tool/option.py Thu Oct 6 16:01:57 2005 @@ -13,8 +13,6 @@ nofaking = 0 parser = "pypy" # "cpython" / "pypy" compiler = "ast" - # "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 = [] @@ -56,7 +54,7 @@ options.append(make_option( '--compiler', action="store", type="string", dest="compiler", help="""select compiling approach. see pypy/doc/README.compiling""", - metavar="[stable|_stable|ast|cpython]")) + metavar="[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/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/ann_override.py (original) +++ pypy/dist/pypy/translator/ann_override.py Thu Oct 6 16:01:57 2005 @@ -29,11 +29,6 @@ clsdef = getbookkeeper().getclassdef(pycode.PyCode) return annmodel.SomeInstance(clsdef) - def override__cpy_stablecompiler(pol, self, parse_result, filename, mode): - from pypy.interpreter import pycode - clsdef = getbookkeeper().getclassdef(pycode.PyCode) - return annmodel.SomeInstance(clsdef) - def specialize__wrap(pol, bookkeeper, mod, spaceop, func, args, mono): from pypy.interpreter.baseobjspace import BaseWrappable ignore, args_w = args.flatten() From arigo at codespeak.net Thu Oct 6 18:35:21 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 18:35:21 +0200 (CEST) Subject: [pypy-svn] r18216 - pypy/dist/pypy/rpython/memory Message-ID: <20051006163521.6A76127B53@code1.codespeak.net> Author: arigo Date: Thu Oct 6 18:35:20 2005 New Revision: 18216 Modified: pypy/dist/pypy/rpython/memory/gc.py Log: Figured out the gc crash on Python 2.3: the collect() of the SemiSpace GC was using tuple packing/unpacking, i.e. it was mallocing during collection :-( This did not show up on 2.4 because CPython optimizes the bytecode to remove the tuple packing/unpacking in this simple case. Obscure. Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Oct 6 18:35:20 2005 @@ -213,10 +213,13 @@ def collect(self): ## print "collecting" - self.fromspace, self.tospace = self.tospace, self.fromspace - self.top_of_space = self.tospace + self.space_size + tospace = self.fromspace + fromspace = self.tospace + self.fromspace = fromspace + self.tospace = tospace + self.top_of_space = tospace + self.space_size roots = self.get_roots() - scan = self.free = self.tospace + scan = self.free = tospace while 1: root = roots.pop() if root == NULL: From arigo at codespeak.net Thu Oct 6 19:11:48 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 19:11:48 +0200 (CEST) Subject: [pypy-svn] r18217 - pypy/extradoc/sprintinfo Message-ID: <20051006171148.9154827B54@code1.codespeak.net> Author: arigo Date: Thu Oct 6 19:11:45 2005 New Revision: 18217 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: mention the confused compiler situation. Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Thu Oct 6 19:11:45 2005 @@ -38,7 +38,11 @@ - try more interp. level optimisations (dicts with string keys, more agressive use of fastcall*...) - compute correct max stack size in compiler (?) -- cleanup our multiple compiler situation (if not already done before the sprint) +- cleanup our multiple compiler situation: remove + testcompiler, fix the tests to work on CPython 2.3 too, + decide what to put in lib-python/modified-2.4.1/compiler -- + stablecompiler or astcompiler? -- and submit it back to + CPython. - (socket module, PEP302) From arigo at codespeak.net Thu Oct 6 19:25:52 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 19:25:52 +0200 (CEST) Subject: [pypy-svn] r18218 - pypy/dist/pypy/interpreter/test Message-ID: <20051006172552.AC4DA27B53@code1.codespeak.net> Author: arigo Date: Thu Oct 6 19:25:51 2005 New Revision: 18218 Modified: pypy/dist/pypy/interpreter/test/test_compiler.py Log: Skip tests that cannot work on 2.3 (sending 2.4 syntax or 2.4 syntax errors to the CPythonCompiler won't work). 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 Oct 6 19:25:51 2005 @@ -1,6 +1,6 @@ import __future__ import autopath -import py +import py, sys from pypy.interpreter.pycompiler import CPythonCompiler, PythonAstCompiler from pypy.interpreter.pycode import PyCode from pypy.interpreter.error import OperationError @@ -327,6 +327,13 @@ def setup_method(self, method): self.compiler = CPythonCompiler(self.space) + if sys.version_info < (2, 4): + def skip_on_2_3(self): + py.test.skip("syntax not supported by the CPython 2.3 compiler") + test_unicodeliterals = skip_on_2_3 + test_none_assignment = skip_on_2_3 + test_import = skip_on_2_3 + class TestPythonAstCompiler(BaseTestCompiler): def setup_method(self, method): self.compiler = PythonAstCompiler(self.space) From arigo at codespeak.net Thu Oct 6 19:30:52 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 19:30:52 +0200 (CEST) Subject: [pypy-svn] r18219 - pypy/extradoc/sprintinfo Message-ID: <20051006173052.11F6B27B54@code1.codespeak.net> Author: arigo Date: Thu Oct 6 19:30:48 2005 New Revision: 18219 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: (pedronis, arigo) Reminder... Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Thu Oct 6 19:30:48 2005 @@ -42,7 +42,7 @@ testcompiler, fix the tests to work on CPython 2.3 too, decide what to put in lib-python/modified-2.4.1/compiler -- stablecompiler or astcompiler? -- and submit it back to - CPython. + CPython. Clean up pyparser/pythonutil.py. - (socket module, PEP302) From arigo at codespeak.net Thu Oct 6 19:53:48 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 19:53:48 +0200 (CEST) Subject: [pypy-svn] r18220 - in pypy/dist/pypy: module/marshal module/marshal/test objspace/std Message-ID: <20051006175348.C0C1127B53@code1.codespeak.net> Author: arigo Date: Thu Oct 6 19:53:48 2005 New Revision: 18220 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/module/marshal/test/test_marshalimpl.py pypy/dist/pypy/objspace/std/marshal_impl.py Log: (pedronis, arigo) Fixes for marshal on 64-bit platforms. Silent a warning on 32-bit platforms with Python 2.3. 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 Thu Oct 6 19:53:48 2005 @@ -362,6 +362,8 @@ b = ord(s[1]) c = ord(s[2]) d = ord(s[3]) + if d & 0x80: + d -= 0x100 x = a | (b<<8) | (c<<16) | (d<<24) return intmask(x) @@ -481,6 +483,8 @@ b = ord(self.bufstr[pos+1]) c = ord(self.bufstr[pos+2]) d = ord(self.bufstr[pos+3]) + if d & 0x80: + d -= 0x100 x = a | (b<<8) | (c<<16) | (d<<24) return intmask(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 Thu Oct 6 19:53:48 2005 @@ -6,6 +6,7 @@ StopIteration Ellipsis 42 + -17 sys.maxint -1.25 -1.25 #2 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 Thu Oct 6 19:53:48 2005 @@ -114,6 +114,25 @@ x = marshal.load(f) assert x == case + def test__minus_17(self): + import sys + hello = "he" + hello += "llo" + def func(x): + return lambda y: x+y + scopefunc = func(42) + import marshal, StringIO + case = -17 + print "case: %-30s func=_minus_17" % (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" 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 Thu Oct 6 19:53:48 2005 @@ -10,3 +10,13 @@ z = 0L z1 = marshal.loads(marshal.dumps(z)) assert z == z1 + + def test_unmarshal_int64(self): + # test that we can unmarshal 64-bit ints on 32-bit platforms + # (of course we only test that if we're running on such a + # platform :-) + import marshal + z = marshal.loads('I\x00\xe4\x0bT\x02\x00\x00\x00') + assert z == 10000000000 + z = marshal.loads('I\x00\x1c\xf4\xab\xfd\xff\xff\xff') + assert z == -10000000000 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 Thu Oct 6 19:53:48 2005 @@ -146,9 +146,9 @@ def unmarshal_Int64(space, u, tc): if LONG_BIT >= 64: - lo = u.get_int() & 0xffff + lo = u.get_int() & (2**32-1) hi = u.get_int() - return W_IntObject(space, (hi << 32) or lo) + return W_IntObject(space, (hi << 32) | lo) else: # fall back to a long # XXX at some point, we need to extend longobject From arigo at codespeak.net Thu Oct 6 20:13:59 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 20:13:59 +0200 (CEST) Subject: [pypy-svn] r18221 - in pypy/dist/pypy/doc: . tool Message-ID: <20051006181359.EA50F27B50@code1.codespeak.net> Author: arigo Date: Thu Oct 6 20:13:59 2005 New Revision: 18221 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/index.txt pypy/dist/pypy/doc/tool/makeref.py Log: (pedronis, arigo) Brought up-to-date the list of main directories in PyPy. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Thu Oct 6 20:13:59 2005 @@ -10,9 +10,10 @@ .. _`interpreter/`: .. _`pypy/interpreter`: ../../pypy/interpreter .. _`pypy/interpreter/argument.py`: ../../pypy/interpreter/argument.py +.. _`interpreter/astcompiler/`: ../../pypy/interpreter/astcompiler .. _`pypy/interpreter/function.py`: ../../pypy/interpreter/function.py -.. _`pypy/interpreter/gateway.py`: -.. _`interpreter/gateway.py`: ../../pypy/interpreter/gateway.py +.. _`interpreter/gateway.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 @@ -27,7 +28,6 @@ .. _`module/__builtin__/`: ../../pypy/module/__builtin__ .. _`pypy/module/__builtin__/__init__.py`: ../../pypy/module/__builtin__/__init__.py .. _`module/_sre/`: ../../pypy/module/_sre -.. _`module/parser/`: ../../pypy/module/parser .. _`module/recparser/`: ../../pypy/module/recparser .. _`module/sys/`: ../../pypy/module/sys .. _`objspace/`: @@ -38,11 +38,12 @@ .. _`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 +.. _`rpython/memory/`: ../../pypy/rpython/memory .. _`pypy/rpython/memory/gc.py`: ../../pypy/rpython/memory/gc.py .. _`pypy/rpython/memory/lladdress.py`: ../../pypy/rpython/memory/lladdress.py .. _`pypy/rpython/memory/simulator.py`: ../../pypy/rpython/memory/simulator.py @@ -58,17 +59,18 @@ .. _`pypy/rpython/test/test_llinterp.py`: ../../pypy/rpython/test/test_llinterp.py .. _`pypy/test_all.py`: ../../pypy/test_all.py .. _`tool/`: ../../pypy/tool +.. _`tool/algo/`: ../../pypy/tool/algo .. _`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 .. _`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/goal/`: ../../pypy/translator/goal .. _`pypy/translator/goal/targetnopstandalone.py`: ../../pypy/translator/goal/targetnopstandalone.py -.. _`translator/java/`: ../../pypy/translator/java .. _`translator/llvm/`: ../../pypy/translator/llvm .. _`translator/tool/`: ../../pypy/translator/tool \ 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 Oct 6 20:13:59 2005 @@ -76,6 +76,9 @@ `interpreter/`_ `bytecode interpreter`_ and related objects (frames, functions, modules,...) +`interpreter/astcompiler/`_ interpreter-level bytecode compiler, via an AST + representation + `lib/`_ PyPy's wholesale reimplementations of CPython modules_ `lib/test2/`_ tests running at interp-level against the reimplementations @@ -87,9 +90,7 @@ `module/__builtin__/`_ full implementation of CPython's ``__builtin__`` module. -`module/parser/`_ parser package from Jonathan David Riehl's `basil`_ package - -`module/recparser/`_ parser package from Logilab +`module/recparser/`_ parser_ package from Logilab `module/sys/`_ implementation of CPython's ``sys`` module. @@ -105,8 +106,14 @@ `rpython/`_ the `RPython Typer`_ +`rpython/memory/`_ experimental `garbage collector`_ construction + framework + `tool/`_ various utilities and hacks used from various places +`tool/algo/`_ general-purpose algorithmic and mathematic + tools + `tool/pytest/`_ support code for our `testing methods`_ `tool/tb_server/`_ a somewhat outdated http-server for presenting @@ -114,16 +121,17 @@ `translator/`_ translation_ backends and support code -`translator/c/`_ the `GenC backend`_ producing a CPython C-extension - module from a given RPython program. - -`translator/java/`_ experimental code to utilize Java for annotation +`translator/c/`_ the `GenC backend`_, producing C code from an + RPython program (generally via the RTyper) `translator/llvm/`_ contains the `LLVM backend`_ producing LLVM assembler from fully annotated RPython programs `translator/tool/`_ helper tools for translation +`translator/goal/`_ currently our main PyPy-translation scripts + live here + ``*/test/`` many directories have a test subdirectory containing test modules (see `Testing in PyPy`_) @@ -152,6 +160,7 @@ .. _`GenC backend`: translation.html#genc .. _`LLVM backend`: translation.html#llvm .. _`revision report`: http://codespeak.net/pypy/rev/current +.. _`garbage collector`: garbage_collection.html .. include:: _ref.txt Modified: pypy/dist/pypy/doc/tool/makeref.py ============================================================================== --- pypy/dist/pypy/doc/tool/makeref.py (original) +++ pypy/dist/pypy/doc/tool/makeref.py Thu Oct 6 20:13:59 2005 @@ -42,6 +42,7 @@ lines = [] for linktarget, linknamelist in items: + linknamelist.sort() for linkname in linknamelist[:-1]: lines.append(".. _`%s`:" % linkname) lines.append(".. _`%s`: %s" %(linknamelist[-1], linktarget)) From arigo at codespeak.net Thu Oct 6 20:28:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 20:28:12 +0200 (CEST) Subject: [pypy-svn] r18222 - pypy/dist/pypy/objspace/std/test Message-ID: <20051006182812.B2FD727B50@code1.codespeak.net> Author: arigo Date: Thu Oct 6 20:28:11 2005 New Revision: 18222 Modified: pypy/dist/pypy/objspace/std/test/test_floatobject.py pypy/dist/pypy/objspace/std/test/test_longobject.py Log: Fix tests for 64-bit machines. 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 Thu Oct 6 20:28:11 2005 @@ -61,7 +61,9 @@ import math assert hash(42.0) == 42 assert hash(42.125) == 1413677056 - assert hash(math.ldexp(0.125, 1000)) == 32 + assert hash(math.ldexp(0.125, 1000)) in ( + 32, # answer on 32-bit machines + 137438953472) # answer on 64-bit machines # testing special overflow values assert hash(1e200 * 1e200) == 314159 assert hash(-1e200 * 1e200) == -271828 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 Thu Oct 6 20:28:11 2005 @@ -393,8 +393,12 @@ assert hash(i) == hash(long(i)) # might check too much -- it's ok to change the hashing algorithm assert hash(123456789L) == 123456789 - assert hash(1234567890123456789L) == -1895067127 - assert hash(-3**333) == -368329968 + assert hash(1234567890123456789L) in ( + -1895067127, # with 32-bit platforms + 1234567890123456789) # with 64-bit platforms + assert hash(-3**333) in ( + -368329968, # with 32-bit platforms + 4437666303107791123) # with 64-bit platforms def math_log(self): import math From arigo at codespeak.net Thu Oct 6 21:09:47 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 21:09:47 +0200 (CEST) Subject: [pypy-svn] r18223 - in pypy/dist/pypy/rpython: . memory Message-ID: <20051006190947.5917B27B51@code1.codespeak.net> Author: arigo Date: Thu Oct 6 21:09:46 2005 New Revision: 18223 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/memory/gc.py Log: * SemiSpaceGC: raise MemoryError instead of going into an infinite recursion when the free space is exhausted * Defaulting space size to 1024 words instead of 4096 bytes, to pass the tests on 64-bit machines as well * A more useful __str__ for LLExceptions in llinterp Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Oct 6 21:09:46 2005 @@ -13,7 +13,9 @@ log = py.log.Producer('llinterp') class LLException(Exception): - pass + def __str__(self): + etype, evalue = self.args + return '' % (''.join(etype.name).rstrip('\x00'),) class LLInterpreter(object): """ low level interpreter working with concrete values. """ @@ -40,8 +42,7 @@ try: return llframe.eval() except LLException, e: - etype, evalue = e.args - print "LLEXCEPTION:", etype.name + print "LLEXCEPTION:", e self.print_traceback() raise except Exception, e: Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Thu Oct 6 21:09:46 2005 @@ -178,7 +178,7 @@ class SemiSpaceGC(GCBase): _alloc_flavor_ = "raw" - def __init__(self, space_size=4096, get_roots=None): + def __init__(self, space_size=1024*int_size, get_roots=None): self.bytes_malloced = 0 self.space_size = space_size self.tospace = raw_malloc(space_size) @@ -204,7 +204,8 @@ self.collect() #XXX need to increase the space size if the object is too big #for bonus points do big objects differently - return self.malloc(typeid, length) + if self.free + totalsize > self.top_of_space: + raise MemoryError result = self.free self.init_gc_object(result, typeid) ## print "mallocing %s, size %s at %s" % (typeid, size, result) From pedronis at codespeak.net Thu Oct 6 21:11:37 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 6 Oct 2005 21:11:37 +0200 (CEST) Subject: [pypy-svn] r18224 - pypy/extradoc/sprintinfo Message-ID: <20051006191137.3946027B51@code1.codespeak.net> Author: pedronis Date: Thu Oct 6 21:11:35 2005 New Revision: 18224 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: another reminder Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Thu Oct 6 21:11:35 2005 @@ -50,6 +50,7 @@ ----------------- - look into implementing weakrefs +- Boehm: fix the all_interior_pointers=0 vs. Windows issue - (improve refcounting) - (passes toward integrating other GCs, rpython/memory) From arigo at codespeak.net Thu Oct 6 22:06:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 6 Oct 2005 22:06:12 +0200 (CEST) Subject: [pypy-svn] r18226 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051006200612.BEC3627B51@code1.codespeak.net> Author: arigo Date: Thu Oct 6 22:06:11 2005 New Revision: 18226 Modified: pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/src/mem.h Log: Reverting this change. We really need the previous version of the settings. Christian found a solution for Windows involving a custom version of the Boehm DLL :-( Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Thu Oct 6 22:06:11 2005 @@ -363,6 +363,7 @@ yield '#define USING_BOEHM_GC' def gc_startup_code(self): + yield 'GC_all_interior_pointers = 0;' yield 'GC_INIT();' 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 Thu Oct 6 22:06:11 2005 @@ -49,10 +49,12 @@ #ifdef USING_BOEHM_GC -#define BOEHM_MALLOC_0_0 GC_MALLOC_IGNORE_OFF_PAGE -#define BOEHM_MALLOC_1_0 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE -#define BOEHM_MALLOC_0_1 GC_MALLOC_IGNORE_OFF_PAGE -#define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE +#define BOEHM_MALLOC_0_0 GC_MALLOC +#define BOEHM_MALLOC_1_0 GC_MALLOC_ATOMIC +#define BOEHM_MALLOC_0_1 GC_MALLOC +#define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC +/* #define BOEHM_MALLOC_0_1 GC_MALLOC_IGNORE_OFF_PAGE */ +/* #define BOEHM_MALLOC_1_1 GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE */ #define OP_BOEHM_ZERO_MALLOC(size, r, is_atomic, is_varsize, err) { \ r = (void*) BOEHM_MALLOC_ ## is_atomic ## _ ## is_varsize (size); \ From ericvrp at codespeak.net Thu Oct 6 22:24:07 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 6 Oct 2005 22:24:07 +0200 (CEST) Subject: [pypy-svn] r18227 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051006202407.406CE27B4E@code1.codespeak.net> Author: ericvrp Date: Thu Oct 6 22:24:04 2005 New Revision: 18227 Added: pypy/dist/pypy/translator/js/ pypy/dist/pypy/translator/js/__init__.py (contents, props changed) pypy/dist/pypy/translator/js/arraynode.py (contents, props changed) pypy/dist/pypy/translator/js/codewriter.py (contents, props changed) pypy/dist/pypy/translator/js/database.py (contents, props changed) pypy/dist/pypy/translator/js/exception.py (contents, props changed) pypy/dist/pypy/translator/js/extfuncnode.py (contents, props changed) pypy/dist/pypy/translator/js/funcnode.py (contents, props changed) pypy/dist/pypy/translator/js/gc.py (contents, props changed) pypy/dist/pypy/translator/js/js.py (contents, props changed) pypy/dist/pypy/translator/js/log.py (contents, props changed) pypy/dist/pypy/translator/js/node.py (contents, props changed) pypy/dist/pypy/translator/js/opaquenode.py (contents, props changed) pypy/dist/pypy/translator/js/opwriter.py (contents, props changed) pypy/dist/pypy/translator/js/structnode.py (contents, props changed) pypy/dist/pypy/translator/js/test/ pypy/dist/pypy/translator/js/test/__init__.py (contents, props changed) pypy/dist/pypy/translator/js/test/runtest.py (contents, props changed) pypy/dist/pypy/translator/js/test/test_trivial.py (contents, props changed) pypy/dist/pypy/translator/js/varsize.py (contents, props changed) Log: Let me be ambitious by adding a Javascript backend. This is at the moment still a stripped down version of the llvm backend and as such does not work! Added: pypy/dist/pypy/translator/js/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/arraynode.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,198 @@ +import py +from pypy.rpython import lltype +from pypy.translator.llvm.log import log +from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode +from pypy.translator.llvm import varsize +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 + 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 + # constructor_decl is used to declare the constructor + # for the array type (see writeimpl) + 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 + + def setup(self): + self.db.prepare_type(self.arraytype) + + # ______________________________________________________________________ + # entry points from genllvm + # + def writedatatypedecl(self, codewriter): + codewriter.arraydef(self.ref, + self.db.get_machine_word(), + self.db.repr_type(self.arraytype)) + + def writedecl(self, codewriter): + # declaration for constructor + codewriter.declare(self.constructor_decl) + + def writeimpl(self, codewriter): + log.writeimpl(self.ref) + varsize.write_constructor(self.db, codewriter, self.ref, + self.constructor_decl, + self.array) + + +class VoidArrayTypeNode(LLVMNode): + __slots__ = "db array ref".split() + + 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) + +class ArrayNode(ConstantLLVMNode): + """ An arraynode. Elements can be + a primitive, + 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 + self.value = value + self.arraytype = lltype.typeOf(value).OF + prefix = '%arrayinstance' + name = '' #str(value).split()[1] + self.ref = self.make_ref(prefix, name) + + def __str__(self): + return "" % (self.ref,) + + def setup(self): + for item in self.value.items: + self.db.prepare_constant(self.arraytype, item) + + p, c = lltype.parentlink(self.value) + p, c = lltype.parentlink(self.value) + if p is not None: + self.db.prepare_constant(lltype.typeOf(p), p) + + def get_length(self): + """ returns logical length of array """ + items = self.value.items + return len(items) + + def get_arrayvalue(self): + items = self.value.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 = self.get_arrayvalue()[0] + 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_type(lltype.typeOf(self.value)) + ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), + self.ref, + typeval) + + p, c = lltype.parentlink(self.value) + 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) + assert p is None, "child arrays are NOT needed by rtyper" + + fromptr = "%s*" % self.get_typerepr() + ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) + return ref + + def get_childref(self, index): + return "getelementptr(%s* %s, int 0, uint 1, int %s)" %( + self.get_typerepr(), + self.ref, + index) + + def constantvalue(self): + physicallen, arrayrepr = self.get_arrayvalue() + 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(), + self.get_length(), + physicallen, + typeval, + arrayrepr) + + s = "%s {%s}" % (self.get_typerepr(), value) + return s + +class StrArrayNode(ArrayNode): + __slots__ = "".split() + + printables = dict([(ord(i), None) for i in + ("0123456789abcdefghijklmnopqrstuvwxyz" + + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + + "!#$%&()*+,-./:;<=>?@[]^_`{|}~ '")]) + + 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: + if ord(c) in StrArrayNode.printables: + s.append(c) + else: + s.append("\\%02x" % ord(c)) + + r = 'c"%s"' % "".join(s) + 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.value = value + prefix = '%arrayinstance' + name = '' #str(value).split()[1] + self.ref = self.make_ref(prefix, name) + + def constantvalue(self): + return "{ %s } {%s %s}" % (self.db.get_machine_word(), + self.db.get_machine_word(), + len(self.value.items)) Added: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/codewriter.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,154 @@ +import py +from itertools import count +from pypy.translator.llvm.log import log + +log = log.codewriter + +DEFAULT_TAIL = '' #/tail +DEFAULT_CCONV = 'fastcc' #ccc/fastcc + +class CodeWriter(object): + def __init__(self, f, genllvm): + self.f = f + self.genllvm = genllvm + self.word = genllvm.db.get_machine_word() + self.uword = genllvm.db.get_machine_uword() + + def append(self, line): + self.f.write(line + '\n') + + def comment(self, line, indent=True): + line = ";; " + line + if indent: + self.indent(line) + else: + self.append(line) + + def newline(self): + self.append("") + + def indent(self, line): + self.append(" " + line) + + def label(self, name): + self.newline() + self.append(" %s:" % name) + + def globalinstance(self, name, typeandata): + self.append("%s = %s global %s" % (name, "internal", typeandata)) + + def structdef(self, name, typereprs): + self.append("%s = type { %s }" %(name, ", ".join(typereprs))) + + 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, + ", ".join(argtypereprs))) + + def declare(self, decl, cconv=DEFAULT_CCONV): + self.append("declare %s %s" %(cconv, decl,)) + + def startimpl(self): + self.newline() + self.append("implementation") + self.newline() + + def br_uncond(self, blockname): + self.indent("br label %%%s" %(blockname,)) + + def br(self, cond, blockname_false, blockname_true): + self.indent("br bool %s, label %%%s, label %%%s" + % (cond, blockname_true, blockname_false)) + + def switch(self, intty, cond, defaultdest, value_label): + labels = '' + for value, label in value_label: + labels += ' %s %s, label %%%s' % (intty, value, label) + self.indent("switch %s %s, label %%%s [%s ]" + % (intty, cond, defaultdest, labels)) + + def openfunc(self, decl, is_entrynode=False, cconv=DEFAULT_CCONV): + self.newline() + #if is_entrynode: + # linkage_type = '' + #else: + # linkage_type = 'internal ' + linkage_type = 'internal ' + self.append("%s%s %s {" % (linkage_type, cconv, decl,)) + + def closefunc(self): + self.append("}") + + def ret(self, type_, ref): + if type_ == 'void': + self.indent("ret void") + else: + self.indent("ret %s %s" % (type_, ref)) + + def phi(self, targetvar, type_, refs, blocknames): + assert targetvar.startswith('%') + assert refs and len(refs) == len(blocknames), "phi node requires blocks" + mergelist = ", ".join( + ["[%s, %%%s]" % item + for item in zip(refs, blocknames)]) + s = "%s = phi %s %s" % (targetvar, type_, mergelist) + self.indent(s) + + def binaryop(self, name, targetvar, type_, ref1, ref2): + self.indent("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) + + def shiftop(self, name, targetvar, type_, ref1, ref2): + self.indent("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) + + #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, label=None, except_label=None, tail=DEFAULT_TAIL, cconv=DEFAULT_CCONV): + if cconv is not 'fastcc': + tail_ = '' + else: + tail_ = tail + if tail_: + tail_ += ' ' + args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) + if except_label: + self.genllvm.exceptionpolicy.invoke(self, targetvar, tail_, cconv, returntype, functionref, args, label, except_label) + else: + if returntype == 'void': + self.indent("%scall %s void %s(%s)" % (tail_, cconv, functionref, args)) + else: + self.indent("%s = %scall %s %s %s(%s)" % (targetvar, tail_, cconv, returntype, functionref, args)) + + def cast(self, targetvar, fromtype, fromvar, targettype): + if fromtype == 'void' and targettype == 'void': + return + self.indent("%(targetvar)s = cast %(fromtype)s " + "%(fromvar)s to %(targettype)s" % locals()) + + def malloc(self, targetvar, type_, size=1, atomic=False, cconv=DEFAULT_CCONV): + for s in self.genllvm.gcpolicy.malloc(targetvar, type_, size, atomic, self.word, self.uword).split('\n'): + self.indent(s) + + def getelementptr(self, targetvar, type, typevar, *indices): + 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) + + def load(self, targetvar, targettype, ptr): + self.indent("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) + + def store(self, valuetype, valuevar, ptr): + self.indent("store %(valuetype)s %(valuevar)s, " + "%(valuetype)s* %(ptr)s" % locals()) + + def debugcomment(self, tempname, len, tmpname): + word = self.word + 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) Added: pypy/dist/pypy/translator/js/database.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/database.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,369 @@ + +import sys + +from pypy.translator.llvm.log import log +from pypy.translator.llvm.funcnode import FuncNode, FuncTypeNode +from pypy.translator.llvm.extfuncnode import ExternalFuncNode +from pypy.translator.llvm.structnode import StructNode, StructVarsizeNode, \ + StructTypeNode, StructVarsizeTypeNode +from pypy.translator.llvm.arraynode import ArrayNode, StrArrayNode, \ + VoidArrayNode, ArrayTypeNode, VoidArrayTypeNode +from pypy.translator.llvm.opaquenode import OpaqueNode, OpaqueTypeNode +from pypy.translator.llvm.node import ConstantLLVMNode +from pypy.rpython import lltype +from pypy.objspace.flow.model import Constant, Variable + +log = log.database + +class Database(object): + def __init__(self, genllvm, translator): + self.genllvm = genllvm + self.translator = translator + self.obj2node = {} + self._pendingsetup = [] + self._tmpcount = 1 + + # 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): + """ internal method for adding comments on each operation """ + tmpname = self.repr_tmpvar() + ".comment" + self._opcomments[op] = (lenofopstr, tmpname) + return tmpname + + def get_op2comment(self, op): + """ internal method for adding comments on each operation """ + return self._opcomments.get(op, None) + + #_______debuggging______________________________________ + + def dump_pbcs(self): + r = "" + for k, v in self.obj2node.iteritems(): + + if isinstance(k, lltype.LowLevelType): + continue + + assert isinstance(lltype.typeOf(k), lltype.ContainerType) + # 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 + + #_______setting up and preperation______________________________ + + def create_constant_node(self, type_, value): + node = None + if isinstance(type_, lltype.FuncType): + if getattr(value._callable, "suggested_primitive", False): + node = ExternalFuncNode(self, value) + else: + node = FuncNode(self, value) + + elif isinstance(type_, lltype.Struct): + if type_._arrayfld: + node = StructVarsizeNode(self, value) + else: + node = StructNode(self, value) + + elif isinstance(type_, lltype.Array): + if type_.OF is lltype.Char: + node = StrArrayNode(self, value) + elif type_.OF is lltype.Void: + node = VoidArrayNode(self, value) + else: + node = ArrayNode(self, value) + + elif isinstance(type_, lltype.OpaqueType): + node = OpaqueNode(self, value) + + assert node is not None, "%s not supported" % (type_) + return node + + def addpending(self, key, node): + # santity check we at least have a key of the right type + assert (isinstance(key, lltype.LowLevelType) 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_type(self, type_): + if type_ in self.obj2node: + return + if isinstance(type_, lltype.Primitive): + pass + elif isinstance(type_, lltype.Ptr): + self.prepare_type(type_.TO) + + elif isinstance(type_, lltype.Struct): + if type_._arrayfld: + self.addpending(type_, StructVarsizeTypeNode(self, type_)) + else: + self.addpending(type_, StructTypeNode(self, type_)) + elif isinstance(type_, lltype.FuncType): + self.addpending(type_, FuncTypeNode(self, type_)) + + elif isinstance(type_, lltype.Array): + if type_.OF is lltype.Void: + self.addpending(type_, VoidArrayTypeNode(self, type_)) + else: + self.addpending(type_, ArrayTypeNode(self, type_)) + + elif isinstance(type_, lltype.OpaqueType): + self.addpending(type_, OpaqueTypeNode(self, type_)) + + else: + assert False, "need to prepare typerepr %s %s" % (type_, type(type_)) + + def prepare_type_multi(self, types): + for type_ in types: + self.prepare_type(type_) + + def prepare_constant(self, type_, value): + if isinstance(type_, lltype.Primitive): + #log.prepareconstant(value, "(is primitive)") + return + + if isinstance(type_, lltype.Ptr): + + type_ = type_.TO + value = value._obj + + #log.prepareconstant("preparing ptr", value) + + # we dont need a node for nulls + if value is None: + return + + # we can share data via pointers + if value not in self.obj2node: + self.addpending(value, self.create_constant_node(type_, value)) + + # always add type (it is safe) + self.prepare_type(type_) + + 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.prepareargvalue("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): + while self._pendingsetup: + node = self._pendingsetup.pop() + #log.settingup(node) + node.setup() + + def set_entrynode(self, key): + self.entrynode = self.obj2node[key] + return self.entrynode + + def getnodes(self): + return self.obj2node.itervalues() + + # __________________________________________________________ + # Representing variables and constants in LLVM source code + + def repr_arg(self, arg): + if isinstance(arg, Constant): + if isinstance(arg.concretetype, lltype.Primitive): + return self.primitive_to_str(arg.concretetype, arg.value) + else: + assert isinstance(arg.value, lltype._ptr) + node = self.obj2node.get(arg.value._obj) + if node is None: + return 'null' + else: + return node.get_ref() + else: + assert isinstance(arg, Variable) + return "%" + str(arg) + + def repr_arg_type(self, arg): + assert isinstance(arg, (Constant, Variable)) + ct = arg.concretetype + return self.repr_type(ct) + + def repr_type(self, type_): + try: + return self.obj2node[type_].ref + except KeyError: + 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" %(type_,)) + + def repr_argwithtype(self, arg): + return self.repr_arg(arg), self.repr_arg_type(arg) + + def repr_arg_multi(self, args): + return [self.repr_arg(arg) for arg in args] + + def repr_arg_type_multi(self, args): + return [self.repr_arg_type(arg) for arg in args] + + def repr_constant(self, value): + " returns node and repr as tuple " + type_ = lltype.typeOf(value) + if isinstance(type_, lltype.Primitive): + repr = self.primitive_to_str(type_, value) + return None, "%s %s" % (self.repr_type(type_), repr) + + elif isinstance(type_, lltype.Ptr): + toptr = self.repr_type(type_) + value = value._obj + + # special case, null pointer + if value is None: + return None, "%s null" % (toptr,) + + node = self.obj2node[value] + ref = node.get_pbcref(toptr) + return node, "%s %s" % (toptr, ref) + + elif isinstance(type_, lltype.Array) or isinstance(type_, lltype.Struct): + node = self.obj2node[value] + return node, node.constantvalue() + + assert False, "%s not supported" % (type(value)) + + def repr_tmpvar(self): + count = self._tmpcount + self._tmpcount += 1 + return "%tmp." + str(count) + + def repr_constructor(self, type_): + return self.obj2node[type_].constructor_ref + + def repr_name(self, obj): + return self.obj2node[obj].ref + + # __________________________________________________________ + # 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) + if sys.byteorder == 'little': + packed = packed[::-1] + + 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 = self.char_to_str(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 + + def get_machine_word(self): + return self.primitives[lltype.Signed] + + 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 get_childref(self, parent, child): + node = self.obj2node[parent] + return node.get_childref(child) Added: pypy/dist/pypy/translator/js/exception.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/exception.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,248 @@ +from pypy.translator.llvm.codewriter import DEFAULT_CCONV + + +class ExceptionPolicy: + RINGBUGGER_SIZE = 8192 + RINGBUFFER_ENTRY_MAXSIZE = 16 + RINGBUGGER_OVERSIZE = RINGBUGGER_SIZE + RINGBUFFER_ENTRY_MAXSIZE + RINGBUFFER_LLVMCODE = ''' +internal fastcc sbyte* %%malloc_exception(uint %%nbytes) { + %%cond = setle uint %%nbytes, %d + br bool %%cond, label %%then, label %%else + +then: + %%tmp.3 = load uint* %%exception_ringbuffer_index + %%tmp.4 = getelementptr [%d x sbyte]* %%exception_ringbuffer, int 0, uint %%tmp.3 + %%tmp.6 = add uint %%tmp.3, %%nbytes + %%tmp.7 = and uint %%tmp.6, %d + store uint %%tmp.7, uint* %%exception_ringbuffer_index + ret sbyte* %%tmp.4 + +else: + %%tmp.8 = call ccc sbyte* %%GC_malloc(uint %%nbytes) + ret sbyte* %%tmp.8 +} +''' % (RINGBUFFER_ENTRY_MAXSIZE, RINGBUGGER_OVERSIZE, RINGBUGGER_SIZE-1) + + def __init__(self): + raise Exception, 'ExceptionPolicy should not be used directly' + + def transform(self, translator, graph=None): + return + + def _noresult(self, returntype): + r = returntype.strip() + if r == 'void': + return 'void' + elif r == 'bool': + return 'bool false' + elif r in 'float double'.split(): + return r + ' 0.0' + elif r in 'ubyte sbyte ushort short uint int ulong long'.split(): + return r + ' 0' + return r + ' null' + + def _nonoderesult(self, node): + decl = node.getdecl() + returntype, name = decl.split(' ', 1) + noresult = self._noresult(returntype) + return noresult + + def new(exceptionpolicy=None): #factory + exceptionpolicy = exceptionpolicy or 'fast' + if exceptionpolicy == 'cpython': + from pypy.translator.llvm.exception import CPythonExceptionPolicy + exceptionpolicy = CPythonExceptionPolicy() + elif exceptionpolicy == 'fast': + from pypy.translator.llvm.exception import FastExceptionPolicy + exceptionpolicy = FastExceptionPolicy() + elif exceptionpolicy == 'none': + from pypy.translator.llvm.exception import NoneExceptionPolicy + exceptionpolicy = NoneExceptionPolicy() + else: + raise Exception, 'unknown exceptionpolicy: ' + str(exceptionpolicy) + return exceptionpolicy + new = staticmethod(new) + + +class NoneExceptionPolicy(ExceptionPolicy): #XXX untested + def __init__(self): + pass + + +class CPythonExceptionPolicy(ExceptionPolicy): #uses issubclass() and llvm invoke&unwind + def __init__(self): + pass + + def llvmcode(self, entrynode): + returntype, entrypointname = entrynode.getdecl().split('%', 1) + noresult = self._noresult(returntype) + cconv = DEFAULT_CCONV + return ''' +ccc %(returntype)s%%__entrypoint__%(entrypointname)s { + %%result = invoke %(cconv)s %(returntype)s%%%(entrypointname)s to label %%no_exception except label %%exception + +no_exception: + store %%RPYTHON_EXCEPTION_VTABLE* null, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type + ret %(returntype)s %%result + +exception: + ret %(noresult)s +} + +ccc int %%__entrypoint__raised_LLVMException() { + %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type + %%result = cast %%RPYTHON_EXCEPTION_VTABLE* %%tmp to int + ret int %%result +} + +internal fastcc void %%unwind() { + unwind +} +''' % locals() + self.RINGBUFFER_LLVMCODE + + def invoke(self, codewriter, targetvar, tail_, cconv, returntype, functionref, args, label, except_label): + labels = 'to label %%%s except label %%%s' % (label, except_label) + if returntype == 'void': + codewriter.indent('%sinvoke %s void %s(%s) %s' % (tail_, cconv, functionref, args, labels)) + else: + codewriter.indent('%s = %sinvoke %s %s %s(%s) %s' % (targetvar, tail_, cconv, returntype, functionref, args, labels)) + + def _is_raise_new_exception(self, db, graph, block): + from pypy.objspace.flow.model import mkentrymap + is_raise_new = False + entrylinks = mkentrymap(graph)[block] + entrylinks = [x for x in entrylinks if x.prevblock is not None] + inputargs = db.repr_arg_multi(block.inputargs) + for i, arg in enumerate(inputargs): + names = db.repr_arg_multi([link.args[i] for link in entrylinks]) + for name in names: #These tests-by-name are a bit yikes, but I don't see a better way right now + if not name.startswith('%last_exception_') and not name.startswith('%last_exc_value_'): + is_raise_new = True + return is_raise_new + + def write_exceptblock(self, funcnode, codewriter, block): + assert len(block.inputargs) == 2 + + db = funcnode.db + graph = funcnode.graph + + if self._is_raise_new_exception(db, graph, block): + funcnode.write_block_phi_nodes(codewriter, block) + + inputargs = db.repr_arg_multi(block.inputargs) + inputargtypes = db.repr_arg_type_multi(block.inputargs) + + 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. + #Which is already stored in the global variables. + #So nothing needs to happen here! + + codewriter.indent('unwind') + + def fetch_exceptions(self, codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value): + for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: + codewriter.label(label) + if last_exc_type_var: + codewriter.load(last_exc_type_var, lltype_of_exception_type, '%last_exception_type') + if last_exc_value_var: + codewriter.load(last_exc_value_var, lltype_of_exception_value, '%last_exception_value') + codewriter.br_uncond(target) + + def reraise(self, funcnode, codewriter): + codewriter.comment('reraise when exception is not caught') + codewriter.indent('unwind') + + def llc_options(self): + return '-enable-correct-eh-support' + + +class FastExceptionPolicy(ExceptionPolicy): #uses issubclass() and last_exception tests after each call + def __init__(self): + self.invoke_count = 0 + + def llvmcode(self, entrynode): + returntype, entrypointname = entrynode.getdecl().split('%', 1) + noresult = self._noresult(returntype) + cconv = DEFAULT_CCONV + return ''' +ccc %(returntype)s%%__entrypoint__%(entrypointname)s { + store %%RPYTHON_EXCEPTION_VTABLE* null, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type + %%result = call %(cconv)s %(returntype)s%%%(entrypointname)s + %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type + %%exc = seteq %%RPYTHON_EXCEPTION_VTABLE* %%tmp, null + br bool %%exc, label %%no_exception, label %%exception + +no_exception: + ret %(returntype)s %%result + +exception: + ret %(noresult)s +} + +ccc int %%__entrypoint__raised_LLVMException() { + %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type + %%result = cast %%RPYTHON_EXCEPTION_VTABLE* %%tmp to int + ret int %%result +} + +internal fastcc void %%unwind() { + ret void +} +''' % locals() + self.RINGBUFFER_LLVMCODE + + def transform(self, translator, graph=None): + from pypy.translator.llvm.backendopt.exception import create_exception_handling + if graph: + create_exception_handling(translator, graph) + else: + for graph in translator.flowgraphs.itervalues(): + create_exception_handling(translator, graph) + #translator.view() + + def invoke(self, codewriter, targetvar, tail_, cconv, returntype, functionref, args, label, except_label): + if returntype == 'void': + codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args)) + else: + codewriter.indent('%s = %scall %s %s %s(%s)' % (targetvar, tail_, cconv, returntype, functionref, args)) + tmp = '%%invoke.tmp.%d' % self.invoke_count + exc = '%%invoke.exc.%d' % self.invoke_count + self.invoke_count += 1 + codewriter.indent('%(tmp)s = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type' % locals()) + codewriter.indent('%(exc)s = seteq %%RPYTHON_EXCEPTION_VTABLE* %(tmp)s, null' % locals()) + codewriter.indent('br bool %(exc)s, label %%%(label)s, label %%%(except_label)s' % locals()) + + def write_exceptblock(self, funcnode, codewriter, block): + assert len(block.inputargs) == 2 + + noresult = self._nonoderesult(funcnode) + + funcnode.write_block_phi_nodes(codewriter, block) + + inputargs = funcnode.db.repr_arg_multi(block.inputargs) + inputargtypes = funcnode.db.repr_arg_type_multi(block.inputargs) + + codewriter.store(inputargtypes[0], inputargs[0], '%last_exception_type') + codewriter.store(inputargtypes[1], inputargs[1], '%last_exception_value') + codewriter.indent('ret ' + noresult) + + def fetch_exceptions(self, codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value): + for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: + codewriter.label(label) + if last_exc_type_var: + codewriter.load(last_exc_type_var, lltype_of_exception_type, '%last_exception_type') + if last_exc_value_var: + codewriter.load(last_exc_value_var, lltype_of_exception_value, '%last_exception_value') + codewriter.store(lltype_of_exception_type , 'null', '%last_exception_type') + codewriter.store(lltype_of_exception_value, 'null', '%last_exception_value') + codewriter.br_uncond(target) + + def reraise(self, funcnode, codewriter): + noresult = self._nonoderesult(funcnode) + codewriter.indent('ret ' + noresult) + + def llc_options(self): + return '' Added: pypy/dist/pypy/translator/js/extfuncnode.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/extfuncnode.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,30 @@ +import py +from pypy.translator.llvm.node import ConstantLLVMNode +from pypy.translator.llvm.log import log +log = log.extfuncnode + +class ExternalFuncNode(ConstantLLVMNode): + used_external_functions = {} + + def __init__(self, db, value): + self.db = db + self.value = value + name = value._callable.__name__ + 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 + 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 + + def writedecl(self, codewriter): + codewriter.declare(self.getdecl()) + + def writeglobalconstants(self, codewriter): + pass Added: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/funcnode.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,217 @@ +import py +import sys +from pypy.objspace.flow.model import Block, Constant, Variable, Link +from pypy.objspace.flow.model import flatten, mkentrymap, traverse, last_exception +from pypy.rpython import lltype +from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode +from pypy.translator.llvm.opwriter import OpWriter +from pypy.translator.llvm.log import log +from pypy.translator.llvm.backendopt.removeexcmallocs import remove_exception_mallocs +from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs +from pypy.translator.unsimplify import remove_double_links +log = log.funcnode + +class FuncTypeNode(LLVMNode): + __slots__ = "db type_ ref".split() + + def __init__(self, db, type_): + self.db = db + assert isinstance(type_, lltype.FuncType) + self.type_ = type_ + self.ref = self.make_ref('%functiontype', '') + + def __str__(self): + return "" % self.ref + + def setup(self): + self.db.prepare_type(self.type_.RESULT) + self.db.prepare_type_multi(self.type_._trueargs()) + + def writedatatypedecl(self, codewriter): + 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): + __slots__ = "db value ref graph block_to_name".split() + + def __init__(self, db, value): + self.db = db + self.value = value + self.ref = self.make_ref('%pypy_', value.graph.name) + self.graph = value.graph + + self.db.genllvm.exceptionpolicy.transform(self.db.translator, self.graph) + remove_exception_mallocs(self.db.translator, self.graph, self.ref) + #merge_mallocs(self.db.translator, self.graph, self.ref) + + remove_double_links(self.db.translator, self.graph) + + def __str__(self): + return "" %(self.ref,) + + def setup(self): + #log("setup", self) + def visit(node): + if isinstance(node, Link): + map(self.db.prepare_arg, node.args) + elif isinstance(node, Block): + 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) + + # ______________________________________________________________________ + # main entry points from genllvm + def writedecl(self, codewriter): + codewriter.declare(self.getdecl()) + + def writeimpl(self, codewriter): + graph = self.graph + log.writeimpl(graph.name) + 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)] + self.block_to_name = {} + for i, block in enumerate(l): + self.block_to_name[block] = "block%s" % i + for block in l: + codewriter.label(self.block_to_name[block]) + for name in 'startblock returnblock exceptblock'.split(): + if block is getattr(graph, name): + getattr(self, 'write_' + name)(codewriter, block) + break + else: + self.write_block(codewriter, block) + codewriter.closefunc() + + def writecomments(self, codewriter): + """ write operations strings for debugging purposes. """ + blocks = [x for x in flatten(self.graph) if isinstance(x, Block)] + for block in blocks: + for op in block.operations: + strop = str(op) + "\n\x00" + l = len(strop) + if strop.find("direct_call") == -1: + continue + tempname = self.db.add_op2comment(l, op) + 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): + pass + + # ______________________________________________________________________ + # writing helpers for entry points + + def getdecl(self): + startblock = self.graph.startblock + returnblock = self.graph.returnblock + startblock_inputargs = [a for a in startblock.inputargs + if a.concretetype is not lltype.Void] + + inputargs = self.db.repr_arg_multi(startblock_inputargs) + inputargtypes = self.db.repr_arg_type_multi(startblock_inputargs) + returntype = self.db.repr_arg_type(self.graph.returnblock.inputargs[0]) + result = "%s %s" % (returntype, self.ref) + args = ["%s %s" % item for item in zip(inputargtypes, inputargs)] + result += "(%s)" % ", ".join(args) + return result + + def write_block(self, codewriter, block): + self.write_block_phi_nodes(codewriter, block) + self.write_block_operations(codewriter, block) + self.write_block_branches(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) + inputargtypes = self.db.repr_arg_type_multi(block.inputargs) + for i, (arg, type_) in enumerate(zip(inputargs, inputargtypes)): + names = self.db.repr_arg_multi([link.args[i] for link in entrylinks]) + blocknames = [self.block_to_name[link.prevblock] + for link in entrylinks] + for i, link in enumerate(entrylinks): #XXX refactor into a transformation + 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": + 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) + 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: + cond = self.db.repr_arg(block.exitswitch) + codewriter.br(cond, self.block_to_name[block.exits[0].target], + self.block_to_name[block.exits[1].target]) + + def write_block_operations(self, codewriter, block): + opwriter = OpWriter(self.db, codewriter, self, block) + 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): + 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): + self.write_block_operations(codewriter, block) + self.write_block_branches(codewriter, block) + + def write_returnblock(self, codewriter, block): + assert len(block.inputargs) == 1 + self.write_block_phi_nodes(codewriter, block) + inputargtype = self.db.repr_arg_type(block.inputargs[0]) + inputarg = self.db.repr_arg(block.inputargs[0]) + codewriter.ret(inputargtype, inputarg) + + def write_exceptblock(self, codewriter, block): + self.db.genllvm.exceptionpolicy.write_exceptblock(self, codewriter, block) Added: pypy/dist/pypy/translator/js/gc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/gc.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,95 @@ +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("llvm") +log.setconsumer("llvm", ansi_log) + + +class GcPolicy: + def __init__(self): + raise Exception, 'GcPolicy should not be used directly' + + def gc_libraries(self): + return [] + + def declarations(self): + return '' + + def malloc(self, targetvar, type_, size, is_atomic, word, uword): + s = str(size) + return '%(targetvar)s = malloc %(type_)s, uint %(s)s' % locals() + + def pyrex_code(self): + return '' + + def new(gcpolicy=None): #factory + gcpolicy = gcpolicy or 'boehm' + + from os.path import exists + boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') + if gcpolicy == 'boehm' and not boehm_on_path: + log.gc.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc') + gcpolicy = 'none' + + if gcpolicy == 'boehm': + from pypy.translator.llvm.gc import BoehmGcPolicy + gcpolicy = BoehmGcPolicy() + elif gcpolicy == 'ref': + from pypy.translator.llvm.gc import RefcountingGcPolicy + gcpolicy = RefcountingGcPolicy() + elif gcpolicy == 'none': + from pypy.translator.llvm.gc import NoneGcPolicy + gcpolicy = NoneGcPolicy() + else: + raise Exception, 'unknown gcpolicy: ' + str(gcpolicy) + return gcpolicy + new = staticmethod(new) + + +class NoneGcPolicy(GcPolicy): + def __init__(self): + pass + + +class BoehmGcPolicy(GcPolicy): + def __init__(self): + self.n_malloced = 0 + + def gc_libraries(self): + return ['gc'] # xxx on windows? + + def declarations(self): + return ''' +declare ccc sbyte* %GC_malloc(uint) +declare ccc sbyte* %GC_malloc_atomic(uint) +%GC_all_interior_pointers = external global int +''' + + def malloc(self, targetvar, type_, size, is_atomic, word, uword): + s = str(size) + self.n_malloced += 1 + cnt = '.%d' % self.n_malloced + atomic = is_atomic and '_atomic' or '' + t = ''' +%%malloc.Size%(cnt)s = getelementptr %(type_)s* null, %(uword)s %(s)s +%%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to %(uword)s +%%malloc.Ptr%(cnt)s = call ccc sbyte* %%GC_malloc%(atomic)s(%(uword)s %%malloc.SizeU%(cnt)s) +%(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s* +''' % locals() + if is_atomic: + t += ''' +call ccc void %%llvm.memset(sbyte* %%malloc.Ptr%(cnt)s, ubyte 0, uint %%malloc.SizeU%(cnt)s, uint 0) +''' % locals() + return t + + def pyrex_code(self): + return ''' +cdef extern int GC_get_heap_size() + +def GC_get_heap_size_wrapper(): + return GC_get_heap_size() +''' + + +class RefcountingGcPolicy(GcPolicy): + def __init__(self): + raise NotImplementedError, 'RefcountingGcPolicy' Added: pypy/dist/pypy/translator/js/js.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/js.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,152 @@ +''' +reference material: + http://webreference.com/javascript/reference/core_ref/ + http://webreference.com/programming/javascript/ + http://mochikit.com/ + +''' + +#import os +#import time +#import types +#import urllib + +import py + +#from pypy.translator.llvm import build_llvm_module +from pypy.translator.llvm.database import Database +#from pypy.translator.llvm.pyxwrapper import write_pyx_wrapper +from pypy.rpython.rmodel import inputconst, getfunctionptr +from pypy.rpython import lltype +from pypy.tool.udir import udir +from pypy.translator.llvm.codewriter import CodeWriter +#from pypy.translator.llvm.codewriter import , DEFAULT_TAIL, DEFAULT_CCONV +#from pypy.translator.llvm import extfuncnode +#from pypy.translator.llvm.module.extfunction import extdeclarations, extfunctions, dependencies +#from pypy.translator.llvm.node import JSNode +#from pypy.translator.llvm.structnode import StructNode +#from pypy.translator.llvm.externs2ll import post_setup_externs, generate_llfile +from pypy.translator.llvm.gc import GcPolicy +from pypy.translator.llvm.exception import ExceptionPolicy +#from pypy.translator.translator import Translator + +from pypy.translator.js.log import log + +function_count = {} +#llexterns_header = llexterns_functions = None + + +class JS(object): # JS = Javascript + + def __init__(self, translator, func=None, gcpolicy=None, exceptionpolicy=None, debug=False): + self.db = Database(self, translator) + self.translator = translator + self.gcpolicy = GcPolicy.new(gcpolicy) + self.exceptionpolicy = ExceptionPolicy.new(exceptionpolicy) + #extfuncnode.ExternalFuncNode.used_external_functions = {} + self.debug = debug # for debug we create comments of every operation that may be executed + if debug: + translator.checkgraphs() + + if func is None: + func = self.translator.entrypoint + self.entrypoint = func + + ptr = getfunctionptr(self.translator, func) + c = inputconst(lltype.typeOf(ptr), ptr) + entry_point = c.value._obj + self.db.prepare_arg_value(c) + + # set up all nodes + self.db.setup_all() + self.entrynode = self.db.set_entrynode(entry_point) + entryfunc_name = self.entrynode.getdecl().split('%', 1)[1].split('(')[0] + + ## post set up externs + #extern_decls = post_setup_externs(self.db) + #self.translator.rtyper.specialize_more_blocks() + #self.db.setup_all() + #using_external_functions = extfuncnode.ExternalFuncNode.used_external_functions.keys() != [] + # + #support_functions = "%raisePyExc_IOError %raisePyExc_ValueError "\ + # "%raisePyExc_OverflowError %raisePyExc_ZeroDivisionError "\ + # "%prepare_ZeroDivisionError %prepare_OverflowError %prepare_ValueError "\ + # "%RPyString_FromString %RPyString_AsString %RPyString_Size".split() + # + #global llexterns_header, llexterns_functions + #if llexterns_header is None and using_external_functions: + # llexterns_header, llexterns_functions = generate_llfile(self.db, extern_decls, support_functions, self.debug) + + # 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='.js') + f = open(str(filename),'w') + codewriter = CodeWriter(f, self) + comment = codewriter.comment + nl = codewriter.newline + + #if using_external_functions: + # nl(); comment("External Function Declarations") ; nl() + # codewriter.append(llexterns_header) + + 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) + + for typ_decl in self.db.getnodes(): + typ_decl.writedatatypedecl(codewriter) + + nl(); comment("Global Data") ; nl() + for typ_decl in self.db.getnodes(): + typ_decl.writeglobalconstants(codewriter) + + nl(); comment("Function Prototypes") ; nl() + #codewriter.append(extdeclarations) + #codewriter.append(self.gcpolicy.declarations()) + + for typ_decl in self.db.getnodes(): + typ_decl.writedecl(codewriter) + + nl(); comment("Function Implementation") + codewriter.startimpl() + + for typ_decl in self.db.getnodes(): + typ_decl.writeimpl(codewriter) + + #codewriter.append(self.exceptionpolicy.llvmcode(self.entrynode)) + # + ## XXX we need to create our own main() that calls the actual entry_point function + #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 support_functions: + # extfuncnode.ExternalFuncNode.used_external_functions[f] = True + # + #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: + # if dep in extfunctions: #else external function that is shared with genc + # codewriter.append(extfunctions[dep][1]) + # depdone[dep] = True + # + #if using_external_functions: + # nl(); comment("External Function Implementation") ; nl() + # codewriter.append(llexterns_functions) + + comment("End of file") ; nl() + self.filename = filename Added: pypy/dist/pypy/translator/js/log.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/log.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,4 @@ +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("js") +log.setconsumer("js", ansi_log) Added: pypy/dist/pypy/translator/js/node.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/node.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,67 @@ +from pypy.rpython import lltype + +class LLVMNode(object): + __slots__ = "".split() + + 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 + else: + postfix = '' + self.nodename_count[name] = 1 + return name + postfix + + def make_ref(self, prefix, name): + return self.make_name(prefix + name) + + def setup(self): + pass + + # __________________ before "implementation" ____________________ + def writedatatypedecl(self, codewriter): + """ write out declare names of data types + (structs/arrays/function pointers) + """ + + def writeglobalconstants(self, codewriter): + """ write out global values. """ + + def writedecl(self, codewriter): + """ write function forward declarations. """ + + def writecomments(self, codewriter): + """ write operations strings for debugging purposes. """ + + # __________________ after "implementation" ____________________ + def writeimpl(self, codewriter): + """ write function implementations. """ + +class ConstantLLVMNode(LLVMNode): + __slots__ = "".split() + + 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()) Added: pypy/dist/pypy/translator/js/opaquenode.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/opaquenode.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,33 @@ +from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode +from pypy.rpython import lltype + +class OpaqueTypeNode(LLVMNode): + + def __init__(self, db, opaquetype): + assert isinstance(opaquetype, lltype.OpaqueType) + self.db = db + self.opaquetype = opaquetype + self.ref = "%%opaquetype.%s" % (opaquetype.tag) + + def __str__(self): + return "" %(self.ref,) + + # ______________________________________________________________________ + # main entry points from genllvm + + def writedatatypedecl(self, codewriter): + # XXX Dummy - not sure what what we want + codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *']) + + +class OpaqueNode(ConstantLLVMNode): + def __init__(self, db, value): + 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 Added: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/opwriter.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,514 @@ +import py +from pypy.objspace.flow.model import Constant +from pypy.rpython import lltype +from pypy.translator.llvm.module.extfunction import extfunctions +from pypy.translator.llvm.extfuncnode import ExternalFuncNode +from pypy.translator.llvm.log import log +log = log.opwriter + +class OpWriter(object): + binary_operations = {'int_mul': 'mul', + 'int_add': 'add', + 'int_sub': 'sub', + 'int_floordiv': 'div', + 'int_mod': 'rem', + 'int_and': 'and', + 'int_or': 'or', + 'int_xor': 'xor', + 'int_lt': 'setlt', + 'int_le': 'setle', + 'int_eq': 'seteq', + 'int_ne': 'setne', + 'int_ge': 'setge', + 'int_gt': 'setgt', + + 'uint_mul': 'mul', + 'uint_add': 'add', + 'uint_sub': 'sub', + 'uint_floordiv': 'div', + 'uint_mod': 'rem', + 'uint_and': 'and', + 'uint_or': 'or', + 'uint_xor': 'xor', + 'uint_lt': 'setlt', + 'uint_le': 'setle', + 'uint_eq': 'seteq', + 'uint_ne': 'setne', + 'uint_ge': 'setge', + 'uint_gt': 'setgt', + + 'unichar_lt': 'setlt', + 'unichar_le': 'setle', + 'unichar_eq': 'seteq', + 'unichar_ne': 'setne', + 'unichar_ge': 'setge', + 'unichar_gt': 'setgt', + + 'float_mul': 'mul', + 'float_add': 'add', + 'float_sub': 'sub', + 'float_truediv': 'div', + 'float_mod': 'rem', + 'float_lt': 'setlt', + 'float_le': 'setle', + 'float_eq': 'seteq', + 'float_ne': 'setne', + 'float_ge': 'setge', + 'float_gt': 'setgt', + + 'ptr_eq': 'seteq', + 'ptr_ne': 'setne', + } + + shift_operations = {'int_lshift': 'shl', + 'int_rshift': 'shr', + + 'uint_lshift': 'shl', + '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 + self.node = node + self.block = block + + def write_operation(self, op): + invoke = op.opname.startswith('invoke:') + if invoke: + self.invoke(op) + else: + if op.opname in self.binary_operations: + 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) + else: + self.cast_primitive(op) + else: + meth = getattr(self, op.opname, None) + if not meth: + raise Exception, "operation %s not found" % op.opname + 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 + try: + 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: + res_val = onestr + else: + res_val = mult_val + for ii in range(operand - 1): + res_val = self.db.repr_tmpvar() + self.codewriter.binaryop("mul", + res_val, + mult_type, + last_val, + mult_val) + last_val = res_val + 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 + + def float_pow(self, op): + self._generic_pow(op, "1.0") + + def _generic_neg(self, op, zerostr): + self.codewriter.binaryop("sub", + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + zerostr, + self.db.repr_arg(op.args[0]), + ) + def int_neg(self, op): + 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") + + def bool_not(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]), + "true") + + 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) + + 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((1L<<32) - 1)) + + def binaryop(self, op): + name = self.binary_operations[op.opname] + assert len(op.args) == 2 + self.codewriter.binaryop(name, + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + 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 + if isinstance(op.args[1], Constant): + tmpvar = self.db.repr_arg(op.args[1]) + else: + tmpvar = self.db.repr_tmpvar() + self.codewriter.cast(tmpvar, self.db.repr_arg_type(op.args[1]), self.db.repr_arg(op.args[1]), 'ubyte') + self.codewriter.shiftop(name, + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + 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 + 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]) + self.codewriter.cast(targetvar, fromtype, fromvar, targettype) + same_as = cast_primitive + + def int_is_true(self, op): + self.codewriter.binaryop("setne", + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + self.db.repr_arg(op.args[0]), + "0") + uint_is_true = int_is_true + + def float_is_true(self, op): + self.codewriter.binaryop("setne", + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + self.db.repr_arg(op.args[0]), + "0.0") + + def ptr_nonzero(self, op): + self.codewriter.binaryop("setne", + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + self.db.repr_arg(op.args[0]), + "null") + + def ptr_iszero(self, op): + self.codewriter.binaryop("seteq", + self.db.repr_arg(op.result), + self.db.repr_arg_type(op.args[0]), + self.db.repr_arg(op.args[0]), + "null") + + def direct_call(self, op): + op_args = [arg for arg in op.args + if arg.concretetype is not lltype.Void] + assert len(op_args) >= 1 + 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:]) + if self.db.is_function_ptr(op.result): + returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) + self.codewriter.call(targetvar,returntype,functionref,argrefs,argtypes) + + def last_exception_type_ptr(self, op): + e = self.db.translator.rtyper.getexceptiondata() + lltype_of_exception_type = ('%structtype.' + e.lltype_of_exception_type.TO.__name__ + '*') + self.codewriter.load('%'+str(op.result), lltype_of_exception_type, '%last_exception_type') + + def invoke(self, op): + 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] + 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) + # XXX commented out for testing + #assert functionref in extfunctions, msg + + assert len(op_args) >= 1 + # at least one label and one exception label + assert len(self.block.exits) >= 2 + + link = self.block.exits[0] + assert link.exitcase is None + + targetvar = self.db.repr_arg(op.result) + returntype = self.db.repr_arg_type(op.result) + argrefs = self.db.repr_arg_multi(op_args[1:]) + argtypes = self.db.repr_arg_type_multi(op_args[1:]) + + none_label = self.node.block_to_name[link.target] + block_label = self.node.block_to_name[self.block] + exc_label = block_label + '_exception_handling' + + if self.db.is_function_ptr(op.result): #use longhand form + returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) + self.codewriter.call(targetvar, returntype, functionref, argrefs, + argtypes, none_label, exc_label) + + e = self.db.translator.rtyper.getexceptiondata() + ll_exception_match = '%pypy_' + e.ll_exception_match.__name__ + 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) + + exc_found_labels, last_exception_type = [], None + catch_all = False + 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() + 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 + + 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 + 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:] + + if current_exception_type.find('getelementptr') == -1: #catch all (except:) + catch_all = True + self.codewriter.br_uncond(exc_found_label) + else: #catch specific exception (class) type + if not last_exception_type: #load pointer only once + 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) + + ep = self.codewriter.genllvm.exceptionpolicy + if not catch_all: + ep.reraise(self.node, self.codewriter) + ep.fetch_exceptions(self.codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value) + + def malloc_exception(self, op): + arg_type = op.args[0].value + targetvar = self.db.repr_arg(op.result) + type_ = self.db.repr_type(arg_type) + tmpvar1 = self.db.repr_tmpvar() + tmpvar2 = self.db.repr_tmpvar() + tmpvar3 = self.db.repr_tmpvar() + self.codewriter.indent('%(tmpvar1)s = getelementptr %(type_)s* null, int 1' % locals()) + self.codewriter.cast(tmpvar2, type_+'*', tmpvar1, 'uint') + self.codewriter.call(tmpvar3, 'sbyte*', '%malloc_exception', [tmpvar2], ['uint']) + self.codewriter.cast(targetvar, 'sbyte*', tmpvar3, type_+'*') + + def malloc(self, op): + arg_type = op.args[0].value + targetvar = self.db.repr_arg(op.result) + type_ = self.db.repr_type(arg_type) + self.codewriter.malloc(targetvar, type_, atomic=arg_type._is_atomic()) + + def malloc_varsize(self, op): + 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 varsized anymore + self.malloc(op) + return + + 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, type_, type_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]) + 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) + else: + self.codewriter.comment("***Skipping operation getfield()***") + + def getsubstruct(self, op): + struct, structtype = self.db.repr_argwithtype(op.args[0]) + 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" + self.codewriter.getelementptr(targetvar, structtype, + struct, ("uint", index)) + + def setfield(self, op): + tmpvar = self.db.repr_tmpvar() + struct, structtype = self.db.repr_argwithtype(op.args[0]) + 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) + else: + self.codewriter.comment("***Skipping operation setfield()***") + + def getarrayitem(self, op): + array, arraytype = self.db.repr_argwithtype(op.args[0]) + index = self.db.repr_arg(op.args[1]) + indextype = self.db.repr_arg_type(op.args[1]) + tmpvar = self.db.repr_tmpvar() + targetvar = self.db.repr_arg(op.result) + targettype = self.db.repr_arg_type(op.result) + if targettype != "void": + self.codewriter.getelementptr(tmpvar, arraytype, array, + ("uint", 1), (indextype, index)) + self.codewriter.load(targetvar, targettype, tmpvar) + else: + self.codewriter.comment("***Skipping operation getarrayitem()***") + + def getarraysubstruct(self, op): + array, arraytype = self.db.repr_argwithtype(op.args[0]) + index = self.db.repr_arg(op.args[1]) + indextype = self.db.repr_arg_type(op.args[1]) + targetvar = self.db.repr_arg(op.result) + self.codewriter.getelementptr(targetvar, arraytype, array, + ("uint", 1), (indextype, index)) + + def setarrayitem(self, op): + array, arraytype = self.db.repr_argwithtype(op.args[0]) + index = self.db.repr_arg(op.args[1]) + indextype = self.db.repr_arg_type(op.args[1]) + + tmpvar = self.db.repr_tmpvar() + + valuevar = self.db.repr_arg(op.args[2]) + valuetype = self.db.repr_arg_type(op.args[2]) + if valuetype != "void": + self.codewriter.getelementptr(tmpvar, arraytype, array, + ("uint", 1), (indextype, index)) + self.codewriter.store(valuetype, valuevar, tmpvar) + 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() + self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 0)) + targetvar = self.db.repr_arg(op.result) + targettype = self.db.repr_arg_type(op.result) + self.codewriter.load(targetvar, targettype, tmpvar) Added: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/structnode.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,235 @@ +import py +from pypy.translator.llvm.log import log +from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode +from pypy.translator.llvm import varsize +from pypy.rpython import lltype + +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 + self.struct = struct + prefix = '%structtype.' + name = self.struct._name + self.ref = self.make_ref(prefix, name) + self.name = self.ref[len(prefix):] + + 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._fields(): + self.db.prepare_type(field) + + # ______________________________________________________________________ + # main entry points from genllvm + + def writedatatypedecl(self, codewriter): + fields_types = [self.db.repr_type(f) for f in self._fields()] + 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) + prefix = '%new.varsizestruct.' + self.constructor_ref = self.make_ref(prefix, self.name) + self.constructor_decl = "%s * %s(%s %%len)" % \ + (self.ref, + self.constructor_ref, + self.db.get_machine_word()) + + def __str__(self): + return "" %(self.ref,) + + # ______________________________________________________________________ + # main entry points from genllvm + + def writedecl(self, codewriter): + # declaration for constructor + codewriter.declare(self.constructor_decl) + + def writeimpl(self, codewriter): + log.writeimpl(self.ref) + + # build up a list of indices to get to the last + # var-sized struct (or rather the according array) + indices_to_array = [] + current = self.struct + while isinstance(current, lltype.Struct): + last_pos = len(current._names_without_voids()) - 1 + 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) + varsize.write_constructor(self.db, + codewriter, + self.ref, + self.constructor_decl, + current, + indices_to_array) + +class StructNode(ConstantLLVMNode): + """ A struct constant. Can simply contain + a primitive, + a struct, + pointer to struct/array + """ + __slots__ = "db value structtype ref _get_ref_cache _get_types".split() + + def __init__(self, db, value): + self.db = db + self.value = value + self.structtype = self.value._TYPE + prefix = '%structinstance.' + name = str(value).split()[1] + self.ref = self.make_ref(prefix, name) + self._get_ref_cache = None + self._get_types = self._compute_types() + + def __str__(self): + return "" % (self.ref,) + + def _compute_types(self): + return [(name, self.structtype._flds[name]) + for name in self.structtype._names_without_voids()] + + def _getvalues(self): + values = [] + for name, T in self._get_types: + value = getattr(self.value, name) + values.append(self.db.repr_constant(value)[1]) + return values + + def setup(self): + for name, T in self._get_types: + assert T is not lltype.Void + value = getattr(self.value, name) + self.db.prepare_constant(T, value) + + p, c = lltype.parentlink(self.value) + if p is not None: + self.db.prepare_constant(lltype.typeOf(p), p) + + def get_typerepr(self): + return self.db.repr_type(self.structtype) + + def get_childref(self, index): + pos = 0 + found = False + for name in self.structtype._names_without_voids(): + if name == index: + 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(), + pos) + + def get_ref(self): + """ Returns a reference as used for operations in blocks. """ + if self._get_ref_cache: + return self._get_ref_cache + p, c = lltype.parentlink(self.value) + if p is None: + ref = self.ref + else: + ref = self.db.get_childref(p, c) + self._get_ref_cache = ref + return ref + + def get_pbcref(self, toptr): + """ Returns a reference as used per pbc. """ + return self.get_ref() + + def constantvalue(self): + """ Returns the constant representation for this node. """ + values = self._getvalues() + all_values = ",\n ".join(values) + return "%s {\n %s\n }\n" % (self.get_typerepr(), all_values) + + +class StructVarsizeNode(StructNode): + """ A varsize struct constant. Can simply contain + a primitive, + a struct, + pointer to struct/array + + and the last element *must* be + an array + OR + a series of embedded structs, which has as its last element an array. + """ + + def __str__(self): + return "" % (self.ref,) + + def _getvalues(self): + values = [] + for name, T in self._get_types[:-1]: + value = getattr(self.value, name) + values.append(self.db.repr_constant(value)[1]) + values.append(self._get_lastnoderepr()) + return values + + def _get_lastnode_helper(self): + lastname, LASTT = self._get_types[-1] + assert isinstance(LASTT, lltype.Array) or ( + isinstance(LASTT, lltype.Struct) and LASTT._arrayfld) + value = getattr(self.value, lastname) + return self.db.repr_constant(value) + + def _get_lastnode(self): + return self._get_lastnode_helper()[0] + + def _get_lastnoderepr(self): + return self._get_lastnode_helper()[1] + + def setup(self): + super(StructVarsizeNode, self).setup() + + def get_typerepr(self): + try: + return self._get_typerepr_cache + except: + # last type is a special case and need to be worked out recursively + types = self._get_types[:-1] + types_repr = [self.db.repr_type(T) for name, T in types] + types_repr.append(self._get_lastnode().get_typerepr()) + result = "{%s}" % ", ".join(types_repr) + self._get_typerepr_cache = result + return result + + def get_ref(self): + if self._get_ref_cache: + return self._get_ref_cache + ref = super(StructVarsizeNode, self).get_ref() + typeval = self.db.repr_type(lltype.typeOf(self.value)) + ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), + ref, + typeval) + self._get_ref_cache = ref + return ref + + def get_pbcref(self, toptr): + """ Returns a reference as used per pbc. """ + ref = self.ref + p, c = lltype.parentlink(self.value) + 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) + return ref Added: pypy/dist/pypy/translator/js/test/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/test/runtest.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,49 @@ +import py, os +from pypy.translator.translator import Translator +from pypy.translator.js.js import JS +from pypy.translator.js.log import log +log = log.runtest + + +def _CLI_is_on_path(): + try: + py.path.local.sysfind('js') #we recommend Spidermonkey + except py.error.ENOENT: + return False + return True + +def write_wrapper(js_filename): + jswrapper_filename = js_filename.new(ext='_wrapper.js') + f = open(str(jswrapper_filename), 'w') + f.write('print(42);\n') + f.close() + log('Written:', jswrapper_filename) + return jswrapper_filename + +class jscallable(object): + def __init__(self, jswrapper_filename): + self.jswrapper_filename = jswrapper_filename + + def __call__(self): + cmd = 'js "%s"' % str(self.jswrapper_filename) + s = os.popen(cmd).read() + e = eval(s) + return e + +def compile(function, annotation=[], view=False): + if not _CLI_is_on_path(): + py.test.skip('Javascript CLI (js) not found') + + t = Translator(function) + a = t.annotate(annotation) + a.simplify() + t.specialize() + t.backend_optimizations() + if view: + t.view() + + js = JS(t, function) + log('Written:', js.filename) + + jswrapper_filename = write_wrapper(js.filename) + return jscallable(jswrapper_filename) Added: pypy/dist/pypy/translator/js/test/test_trivial.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/test/test_trivial.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,8 @@ +import py +from pypy.translator.js.test.runtest import compile + +def test_CLI(): + def simple1(): + return 42 + f = compile(simple1) + assert f() == simple1() Added: pypy/dist/pypy/translator/js/varsize.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/varsize.py Thu Oct 6 22:24:04 2005 @@ -0,0 +1,38 @@ +from pypy.rpython.rstr import STR + +def write_constructor(db, codewriter, ref, constructor_decl, ARRAY, + indices_to_array=()): + + #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) + word = lentype = db.get_machine_word() + uword = db.get_machine_uword() + + 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", uword) + codewriter.malloc("%ptr", "sbyte", "%usize", atomic=ARRAY._is_atomic()) + codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") + + 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_arraylength) + codewriter.store(lentype, "%len", "%arraylength") + + codewriter.ret(ref + "*", "%result") + codewriter.closefunc() + From tismer at codespeak.net Thu Oct 6 23:26:22 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 6 Oct 2005 23:26:22 +0200 (CEST) Subject: [pypy-svn] r18231 - pypy/dist/pypy/translator/c Message-ID: <20051006212622.C5D4327B51@code1.codespeak.net> Author: tismer Date: Thu Oct 6 23:26:22 2005 New Revision: 18231 Modified: pypy/dist/pypy/translator/c/gc.py Log: a small patch, currently just addressing windows, for a specific build of gc. I hope somebody will do something related for the other platforms. Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Thu Oct 6 23:26:22 2005 @@ -353,7 +353,9 @@ return result def gc_libraries(self): - return ['gc'] # xxx on windows? + if sys.platform == 'win32': + return ['gc_pypy'] + return ['gc'] def pre_pre_gc_code(self): #if sys.platform == "linux2": @@ -363,8 +365,11 @@ yield '#define USING_BOEHM_GC' def gc_startup_code(self): - yield 'GC_all_interior_pointers = 0;' - yield 'GC_INIT();' + if sys.platform == 'win32': + yield 'assert GC_all_interior_pointers == 0;' + else: + yield 'GC_all_interior_pointers = 0;' + yield 'GC_INIT();' class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode): From tismer at codespeak.net Thu Oct 6 23:28:47 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 6 Oct 2005 23:28:47 +0200 (CEST) Subject: [pypy-svn] r18232 - pypy/dist/pypy/translator/win32 Message-ID: <20051006212847.0119D27B51@code1.codespeak.net> Author: tismer Date: Thu Oct 6 23:28:46 2005 New Revision: 18232 Added: pypy/dist/pypy/translator/win32/ pypy/dist/pypy/translator/win32/gc_patch_windows.py (contents, props changed) Log: a windows-specific helper script for the Boehm gc, including some instructions how to set this up easily on Windows. Added: pypy/dist/pypy/translator/win32/gc_patch_windows.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/win32/gc_patch_windows.py Thu Oct 6 23:28:46 2005 @@ -0,0 +1,99 @@ +# patches for the Boehm GC for PyPy under Windows + +""" +How to build a pypy compatible version of the Boehm collector +for Windows and Visual Studio .net 2003. + +First of all, download the official Boehm collector suite +from http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc.tar.gz +At the time of writing (2005-10-06) this contains version gc6.5 . + +Unpack this folder somewhere, for instance to "d:\tmp". +Change to this folder using + +d: +cd \tmp\gc6.5 + +Then copy the file NT_THREADS_MAKEFILE to Makefile: + +copy NT_THREADS_MAKEFILE Makefile + +This file is the general-purpose gc dllmakefile. For some internal +reasons, this file's defaults are bad for PyPy. Use this script to +do a patch: (assuming that you have d:\pypy\dist\pypy\translator\goal) + +python d:\pypy\dist\pypy\translator\goal\gc_patch_windows.py + +Now, your makefile is patched a little bit. In particular, + +ALL_INTERIOR_POINTERS is now undefined, which PyPy wants to have +NO_GETENV is specified, since we don't want dependencies + +and the name of the .lib and .dll files is changed to gc_pypy.??? + +Now you need to build your gc, either as a debug or as a release +build. First of all, make sure that you have your environment prepared. + +With my setup, I have to do + +"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\bin\vcvars32.bat" + +After that, you can either build a release or a debug gc. + +After a successful build, you need to enable gc_pypy.dll for your compiler. +There are many ways to install this. The followong recommendation just +works without changing your environment variables. I think this is the +easiest way possible, but this is a matter of taste. What I did is: + +nmake CFG="gc - Win32 Release" + +After the build, you will find a gc_pypy.dll file in the Release folder. +Copy this file to c:\windows\system32 or any other folder that is always +in your PATH variable. + +Also, copy Release\gc_pypy.lib to (in my case) +"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib" + +That's all, folks! + +In case of a debug build, replace "Release" by "Debug", and also copy +gc_pypy.pdb to your lib folder. This allows you to use source-level +debugging. + +Please use the above recipe and report any bugs to me. + +cheers - chris +""" + +REPLACE = { + '"ALL_INTERIOR_POINTERS"': '"NO_GETENV"', + } + +for ending in "lib exp map pdb bsc dll pch".split(): + REPLACE["gc.%s" % ending] = "gc_pypy.%s" % ending + +def change_settings(src): + for old, new in REPLACE.items(): + newsrc = src.replace(old, new) + if newsrc == src: + raise ValueError, "this makefile does not contain %s" % old + src = newsrc + return src + +def find_file(): + import os + for name in os.listdir("."): + if name.lower() == 'makefile': + return name + else: + raise ValueError, 'Makefile not found' + +try: + name = find_file() + source = change_settings(file(name).read()) + file(name, "w").write(source) + print "Updated your Makefile to fit PyPy's needs. Your lib will be named gc_pypy.dll" + print "and gc_pypy.lib. Please put them into appropriate places, see __doc__." +except: + print __doc__ + raise From tismer at codespeak.net Thu Oct 6 23:32:33 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 6 Oct 2005 23:32:33 +0200 (CEST) Subject: [pypy-svn] r18233 - pypy/dist/pypy/translator/win32 Message-ID: <20051006213233.8C14827B4E@code1.codespeak.net> Author: tismer Date: Thu Oct 6 23:32:32 2005 New Revision: 18233 Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py Log: forgot about the include stuff,added now Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py ============================================================================== --- pypy/dist/pypy/translator/win32/gc_patch_windows.py (original) +++ pypy/dist/pypy/translator/win32/gc_patch_windows.py Thu Oct 6 23:32:32 2005 @@ -18,7 +18,7 @@ copy NT_THREADS_MAKEFILE Makefile -This file is the general-purpose gc dllmakefile. For some internal +This file is the general-purpose gc dll makefile. For some internal reasons, this file's defaults are bad for PyPy. Use this script to do a patch: (assuming that you have d:\pypy\dist\pypy\translator\goal) @@ -52,7 +52,11 @@ in your PATH variable. Also, copy Release\gc_pypy.lib to (in my case) -"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib" +"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib"; + +finally, copy d:\tmpgc6.5\include to +"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include" +and rename this folder to "gc", so that "gc/gc.h" is valid. That's all, folks! From tismer at codespeak.net Thu Oct 6 23:44:45 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 6 Oct 2005 23:44:45 +0200 (CEST) Subject: [pypy-svn] r18235 - pypy/dist/pypy/translator/win32 Message-ID: <20051006214445.E6A5527B4E@code1.codespeak.net> Author: tismer Date: Thu Oct 6 23:44:44 2005 New Revision: 18235 Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py Log: just something more to say... Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py ============================================================================== --- pypy/dist/pypy/translator/win32/gc_patch_windows.py (original) +++ pypy/dist/pypy/translator/win32/gc_patch_windows.py Thu Oct 6 23:44:44 2005 @@ -62,9 +62,12 @@ In case of a debug build, replace "Release" by "Debug", and also copy gc_pypy.pdb to your lib folder. This allows you to use source-level -debugging. +debugging. Please note: If you want to both build the default gc.dll +and gc_pypy.dll, please delete the Debug resp. Release folders in +between. The generated .sbr files are in the way. Please use the above recipe and report any bugs to me. +In case of trouble, I also can provide you with pre-built dlls. cheers - chris """ From tismer at codespeak.net Thu Oct 6 23:56:49 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Thu, 6 Oct 2005 23:56:49 +0200 (CEST) Subject: [pypy-svn] r18236 - pypy/dist/pypy/translator/win32 Message-ID: <20051006215649.1B5F427B4E@code1.codespeak.net> Author: tismer Date: Thu Oct 6 23:56:48 2005 New Revision: 18236 Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py Log: finalisation, concluding script, well... Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py ============================================================================== --- pypy/dist/pypy/translator/win32/gc_patch_windows.py (original) +++ pypy/dist/pypy/translator/win32/gc_patch_windows.py Thu Oct 6 23:56:48 2005 @@ -19,10 +19,11 @@ copy NT_THREADS_MAKEFILE Makefile This file is the general-purpose gc dll makefile. For some internal -reasons, this file's defaults are bad for PyPy. Use this script to +reasons, this file's defaults are bad for PyPy. The early initialisation +in DllMain() inhibits the changes necessary for PyPy. Use this script to do a patch: (assuming that you have d:\pypy\dist\pypy\translator\goal) -python d:\pypy\dist\pypy\translator\goal\gc_patch_windows.py +python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py Now, your makefile is patched a little bit. In particular, @@ -41,7 +42,7 @@ After that, you can either build a release or a debug gc. After a successful build, you need to enable gc_pypy.dll for your compiler. -There are many ways to install this. The followong recommendation just +There are many ways to install this. The following recommendation just works without changing your environment variables. I think this is the easiest way possible, but this is a matter of taste. What I did is: @@ -54,7 +55,7 @@ Also, copy Release\gc_pypy.lib to (in my case) "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib"; -finally, copy d:\tmpgc6.5\include to +finally, copy d:\tmp\gc6.5\include to "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include" and rename this folder to "gc", so that "gc/gc.h" is valid. @@ -68,6 +69,22 @@ Please use the above recipe and report any bugs to me. In case of trouble, I also can provide you with pre-built dlls. +Note: We also could have solved this by including the gc source +into the PyPy build. This may or may not become necessary if something +changes dramatically, again. As long as this is not needed, I prefer +this simple solution. + +Summary transcript of the steps involved: (please adjust paths) + +d: +cd \tmp\gc6.5 +copy NT_THREADS_MAKEFILE Makefile +python d:\pypy\dist\pypy\translator\goal\win32\gc_patch_windows.py +"e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\bin\vcvars32.bat" +nmake CFG="gc - Win32 Release" +copy Release\gc_pypy.dll c:\windows\system32 +copy Release\gc_pypy.lib "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib" +copy include "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\gc" cheers - chris """ From tismer at codespeak.net Fri Oct 7 00:05:04 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 7 Oct 2005 00:05:04 +0200 (CEST) Subject: [pypy-svn] r18237 - pypy/dist/pypy/translator/win32 Message-ID: <20051006220504.7894027B51@code1.codespeak.net> Author: tismer Date: Fri Oct 7 00:05:03 2005 New Revision: 18237 Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py Log: yuck, windows is so boring... Modified: pypy/dist/pypy/translator/win32/gc_patch_windows.py ============================================================================== --- pypy/dist/pypy/translator/win32/gc_patch_windows.py (original) +++ pypy/dist/pypy/translator/win32/gc_patch_windows.py Fri Oct 7 00:05:03 2005 @@ -84,6 +84,7 @@ nmake CFG="gc - Win32 Release" copy Release\gc_pypy.dll c:\windows\system32 copy Release\gc_pypy.lib "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\lib" +mkdir "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\gc" copy include "e:\Programme\Microsoft Visual Studio .NET 2003\Vc7\include\gc" cheers - chris From tismer at codespeak.net Fri Oct 7 00:22:28 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 7 Oct 2005 00:22:28 +0200 (CEST) Subject: [pypy-svn] r18238 - in pypy/dist/pypy/translator: goal/win32 win32 Message-ID: <20051006222228.F0BDE27B50@code1.codespeak.net> Author: tismer Date: Fri Oct 7 00:22:27 2005 New Revision: 18238 Added: pypy/dist/pypy/translator/goal/win32/ - copied from r18236, pypy/dist/pypy/translator/win32/ pypy/dist/pypy/translator/goal/win32/gc_patch_windows.py - copied unchanged from r18237, pypy/dist/pypy/translator/win32/gc_patch_windows.py Removed: pypy/dist/pypy/translator/win32/ Log: maybe this is correct,now? From tismer at codespeak.net Fri Oct 7 01:08:00 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 7 Oct 2005 01:08:00 +0200 (CEST) Subject: [pypy-svn] r18239 - pypy/dist/pypy/translator/c Message-ID: <20051006230800.8DEEE27B4E@code1.codespeak.net> Author: tismer Date: Fri Oct 7 01:07:59 2005 New Revision: 18239 Modified: pypy/dist/pypy/translator/c/gc.py Log: oupps, got used too much to Python asserts... Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Fri Oct 7 01:07:59 2005 @@ -366,7 +366,7 @@ def gc_startup_code(self): if sys.platform == 'win32': - yield 'assert GC_all_interior_pointers == 0;' + yield 'assert(GC_all_interior_pointers == 0);' else: yield 'GC_all_interior_pointers = 0;' yield 'GC_INIT();' From pedronis at codespeak.net Fri Oct 7 02:56:19 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 7 Oct 2005 02:56:19 +0200 (CEST) Subject: [pypy-svn] r18240 - pypy/dist/pypy/interpreter/stablecompiler Message-ID: <20051007005619.790CD27B4E@code1.codespeak.net> Author: pedronis Date: Fri Oct 7 02:56:17 2005 New Revision: 18240 Added: pypy/dist/pypy/interpreter/stablecompiler/ - copied from r18214, pypy/dist/pypy/interpreter/stablecompiler/ Log: resurrect stable compiler From pedronis at codespeak.net Fri Oct 7 02:57:02 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 7 Oct 2005 02:57:02 +0200 (CEST) Subject: [pypy-svn] r18241 - pypy/dist/pypy/module/recparser/test Message-ID: <20051007005702.255C627B4E@code1.codespeak.net> Author: pedronis Date: Fri Oct 7 02:57:00 2005 New Revision: 18241 Modified: pypy/dist/pypy/module/recparser/test/ (props changed) Log: svn:ignore From pedronis at codespeak.net Fri Oct 7 02:59:48 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 7 Oct 2005 02:59:48 +0200 (CEST) Subject: [pypy-svn] r18242 - in pypy/dist/pypy/interpreter: pyparser/test pyparser/test/samples testcompiler Message-ID: <20051007005948.1367F27B4E@code1.codespeak.net> Author: pedronis Date: Fri Oct 7 02:59:44 2005 New Revision: 18242 Removed: pypy/dist/pypy/interpreter/testcompiler/ Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_decorators.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py pypy/dist/pypy/interpreter/pyparser/test/test_samples.py Log: use the resurrected stablecompiler in astbuilder/astcompiler tests so they work on 2.3 too kill instead testcompiler PS: it seems beacause of a typo 'single' mode is not tested, kept thing this way but we should look into this, if fixed some tests fail Modified: pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_decorators.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_decorators.py (original) +++ pypy/dist/pypy/interpreter/pyparser/test/samples/snippet_decorators.py Fri Oct 7 02:59:44 2005 @@ -5,7 +5,7 @@ @accepts(int, (int,float)) @returns((int,float)) -def func(arg1, arg2): +def func0(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 Fri Oct 7 02:59:44 2005 @@ -3,8 +3,8 @@ 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.testcompiler.transformer import Transformer -import pypy.interpreter.testcompiler.ast as test_ast +from pypy.interpreter.stablecompiler.transformer import Transformer +import pypy.interpreter.stablecompiler.ast as test_ast import pypy.interpreter.astcompiler.ast as ast_ast import py.test 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 Oct 7 02:59:44 2005 @@ -1,13 +1,11 @@ import os from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER from pypy.interpreter.pyparser.astbuilder import AstBuilder +from pypy.interpreter.pyparser.tuplebuilder import TupleBuilder from pypy.interpreter.pycode import PyCode import py.test def setup_module(mod): - import sys - if sys.version[:3] != "2.4": - py.test.skip("expected to work only on 2.4") import pypy.conftest mod.std_space = pypy.conftest.getobjspace('std') @@ -70,7 +68,7 @@ def compile_with_astcompiler(expr, target='exec', space=FakeSpace()): - ast = ast_parse_expr(expr, target='exec', space=space) + ast = ast_parse_expr(expr, target='exec', space=space) # xxx exec: single not really tested, mumble misc.set_filename('', ast) if target == 'exec': Generator = pycodegen.ModuleCodeGenerator @@ -82,10 +80,23 @@ rcode = codegen.getCode() return rcode -def compile_with_testcompiler(expr, target='exec'): - from pypy.interpreter.testcompiler import compile - # from compiler import compile - return compile(expr, '', target) +def compile_with_testcompiler(expr, target='exec', space=FakeSpace()): + target2 = TARGET_DICT['exec'] # xxx exec: single not really tested + builder = TupleBuilder() + PYTHON_PARSER.parse_source(expr, target2, builder) + tuples = builder.stack[-1].as_tuple(True) + from pypy.interpreter.stablecompiler import transformer, pycodegen, misc + ast = transformer.Transformer('').compile_node(tuples) + misc.set_filename('', ast) + if target == 'exec': + Generator = pycodegen.ModuleCodeGenerator + elif target == 'single': + Generator = pycodegen.InteractiveCodeGenerator + elif target == 'eval': + Generator = pycodegen.ExpressionCodeGenerator + codegen = Generator(ast) + rcode = codegen.getCode() + return rcode def compare_code(ac_code, sc_code, space=FakeSpace()): 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 Fri Oct 7 02:59:44 2005 @@ -93,7 +93,7 @@ assert False, testname -from pypy.interpreter.testcompiler.transformer import Transformer as PyPyTransformer +from pypy.interpreter.stablecompiler.transformer import Transformer as PyPyTransformer from compiler.transformer import Transformer as PythonTransformer def _check_tuples_equality(pypy_tuples, python_tuples, testname): From tismer at codespeak.net Fri Oct 7 04:20:48 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 7 Oct 2005 04:20:48 +0200 (CEST) Subject: [pypy-svn] r18243 - pypy/dist/pypy/translator/c Message-ID: <20051007022048.7170E27B4D@code1.codespeak.net> Author: tismer Date: Fri Oct 7 04:20:47 2005 New Revision: 18243 Modified: pypy/dist/pypy/translator/c/gc.py Log: better safe than sorry! Always initialize Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Fri Oct 7 04:20:47 2005 @@ -369,7 +369,7 @@ yield 'assert(GC_all_interior_pointers == 0);' else: yield 'GC_all_interior_pointers = 0;' - yield 'GC_INIT();' + yield 'GC_INIT();' class BoehmGcRuntimeTypeInfo_OpaqueNode(ContainerNode): From ac at codespeak.net Fri Oct 7 11:26:08 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 7 Oct 2005 11:26:08 +0200 (CEST) Subject: [pypy-svn] r18252 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20051007092608.4DF6927B58@code1.codespeak.net> Author: ac Date: Fri Oct 7 11:26:08 2005 New Revision: 18252 Added: pypy/dist/lib-python/modified-2.4.1/test/test_trace.py - copied, changed from r18248, pypy/dist/lib-python/2.4.1/test/test_trace.py Log: Make sure the 'except' line gets a lineno so it can be jumped to. From ac at codespeak.net Fri Oct 7 11:27:41 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 7 Oct 2005 11:27:41 +0200 (CEST) Subject: [pypy-svn] r18253 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20051007092741.6052827B58@code1.codespeak.net> Author: ac Date: Fri Oct 7 11:27:41 2005 New Revision: 18253 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py Log: Do not generate lineno before the implicit return. Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Fri Oct 7 11:27:41 2005 @@ -564,6 +564,10 @@ end = {} forward_refs = [] for b in self.orderedblocks: + # Prune any setlineno before the 'implicit return' block. + if b is self.exit: + while len(insts) and insts[-1].op == "SET_LINENO": + insts.pop() begin[b] = pc for inst in b.getInstructions(): if not inst.has_arg: From ericvrp at codespeak.net Fri Oct 7 12:07:59 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 7 Oct 2005 12:07:59 +0200 (CEST) Subject: [pypy-svn] r18256 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051007100759.DE77727B58@code1.codespeak.net> Author: ericvrp Date: Fri Oct 7 12:07:58 2005 New Revision: 18256 Added: pypy/dist/pypy/translator/js/test/test_runtest.py - copied, changed from r18227, pypy/dist/pypy/translator/js/test/test_trivial.py Removed: pypy/dist/pypy/translator/js/test/test_trivial.py Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/exception.py pypy/dist/pypy/translator/js/gc.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/log.py pypy/dist/pypy/translator/js/test/runtest.py Log: Lots of changes All 'old' code is still put in the js code for documentation purposes. Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Fri Oct 7 12:07:58 2005 @@ -18,7 +18,7 @@ self.f.write(line + '\n') def comment(self, line, indent=True): - line = ";; " + line + line = "// " + line if indent: self.indent(line) else: @@ -32,60 +32,55 @@ def label(self, name): self.newline() - self.append(" %s:" % name) + self.append("// QQQ %s:" % name) def globalinstance(self, name, typeandata): - self.append("%s = %s global %s" % (name, "internal", typeandata)) + self.append("// QQQ %s = %s global %s" % (name, "internal", typeandata)) def structdef(self, name, typereprs): - self.append("%s = type { %s }" %(name, ", ".join(typereprs))) + self.append("// QQQ %s = type { %s }" %(name, ", ".join(typereprs))) def arraydef(self, name, lentype, typerepr): - self.append("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr)) + self.append("// QQQ %s = type { %s, [0 x %s] }" % (name, lentype, typerepr)) def funcdef(self, name, rettyperepr, argtypereprs): - self.append("%s = type %s (%s)" % (name, rettyperepr, + self.append("// QQQ %s = type %s (%s)" % (name, rettyperepr, ", ".join(argtypereprs))) def declare(self, decl, cconv=DEFAULT_CCONV): - self.append("declare %s %s" %(cconv, decl,)) + self.append("// QQQ declare %s %s" %(cconv, decl,)) def startimpl(self): self.newline() - self.append("implementation") + self.append("// QQQ implementation") self.newline() def br_uncond(self, blockname): - self.indent("br label %%%s" %(blockname,)) + self.indent("// QQQ br label %%%s" %(blockname,)) def br(self, cond, blockname_false, blockname_true): - self.indent("br bool %s, label %%%s, label %%%s" + self.indent("// QQQ br bool %s, label %%%s, label %%%s" % (cond, blockname_true, blockname_false)) def switch(self, intty, cond, defaultdest, value_label): labels = '' for value, label in value_label: labels += ' %s %s, label %%%s' % (intty, value, label) - self.indent("switch %s %s, label %%%s [%s ]" + self.indent("// QQQ switch %s %s, label %%%s [%s ]" % (intty, cond, defaultdest, labels)) def openfunc(self, decl, is_entrynode=False, cconv=DEFAULT_CCONV): self.newline() - #if is_entrynode: - # linkage_type = '' - #else: - # linkage_type = 'internal ' - linkage_type = 'internal ' - self.append("%s%s %s {" % (linkage_type, cconv, decl,)) + self.append("%s {" % decl) def closefunc(self): self.append("}") def ret(self, type_, ref): - if type_ == 'void': - self.indent("ret void") + if type_ == '// QQQ void': + self.indent("// QQQ ret void") else: - self.indent("ret %s %s" % (type_, ref)) + self.indent("// QQQ ret %s %s" % (type_, ref)) def phi(self, targetvar, type_, refs, blocknames): assert targetvar.startswith('%') @@ -94,19 +89,14 @@ ["[%s, %%%s]" % item for item in zip(refs, blocknames)]) s = "%s = phi %s %s" % (targetvar, type_, mergelist) - self.indent(s) + self.indent('// QQQ ' + s) def binaryop(self, name, targetvar, type_, ref1, ref2): - self.indent("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) + self.indent("// QQQ %s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) def shiftop(self, name, targetvar, type_, ref1, ref2): - self.indent("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) + self.indent("// QQQ %s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) - #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, label=None, except_label=None, tail=DEFAULT_TAIL, cconv=DEFAULT_CCONV): if cconv is not 'fastcc': tail_ = '' @@ -119,31 +109,31 @@ self.genllvm.exceptionpolicy.invoke(self, targetvar, tail_, cconv, returntype, functionref, args, label, except_label) else: if returntype == 'void': - self.indent("%scall %s void %s(%s)" % (tail_, cconv, functionref, args)) + self.indent("// QQQ call void %s(%s)" % (functionref, args)) else: - self.indent("%s = %scall %s %s %s(%s)" % (targetvar, tail_, cconv, returntype, functionref, args)) + self.indent("// QQQ %s = call %s %s(%s)" % (targetvar, returntype, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): if fromtype == 'void' and targettype == 'void': return - self.indent("%(targetvar)s = cast %(fromtype)s " + self.indent("// QQQ %(targetvar)s = cast %(fromtype)s " "%(fromvar)s to %(targettype)s" % locals()) def malloc(self, targetvar, type_, size=1, atomic=False, cconv=DEFAULT_CCONV): for s in self.genllvm.gcpolicy.malloc(targetvar, type_, size, atomic, self.word, self.uword).split('\n'): - self.indent(s) + self.indent('// QQQ ' + s) def getelementptr(self, targetvar, type, typevar, *indices): 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) + self.indent('// QQQ ' + res) def load(self, targetvar, targettype, ptr): - self.indent("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) + self.indent("// QQQ %(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) def store(self, valuetype, valuevar, ptr): - self.indent("store %(valuetype)s %(valuevar)s, " + self.indent("// QQQ store %(valuetype)s %(valuevar)s, " "%(valuetype)s* %(ptr)s" % locals()) def debugcomment(self, tempname, len, tmpname): @@ -151,4 +141,4 @@ 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) + self.indent('// QQQ ' + res) Modified: pypy/dist/pypy/translator/js/exception.py ============================================================================== --- pypy/dist/pypy/translator/js/exception.py (original) +++ pypy/dist/pypy/translator/js/exception.py Fri Oct 7 12:07:58 2005 @@ -49,13 +49,13 @@ return noresult def new(exceptionpolicy=None): #factory - exceptionpolicy = exceptionpolicy or 'fast' - if exceptionpolicy == 'cpython': - from pypy.translator.llvm.exception import CPythonExceptionPolicy - exceptionpolicy = CPythonExceptionPolicy() - elif exceptionpolicy == 'fast': - from pypy.translator.llvm.exception import FastExceptionPolicy - exceptionpolicy = FastExceptionPolicy() + exceptionpolicy = exceptionpolicy or 'explicit' + if exceptionpolicy == 'invokeunwind': + from pypy.translator.llvm.exception import InvokeUnwindExceptionPolicy + exceptionpolicy = InvokeUnwindExceptionPolicy() + elif exceptionpolicy == 'explicit': + from pypy.translator.llvm.exception import ExplicitExceptionPolicy + exceptionpolicy = ExplicitExceptionPolicy() elif exceptionpolicy == 'none': from pypy.translator.llvm.exception import NoneExceptionPolicy exceptionpolicy = NoneExceptionPolicy() @@ -70,7 +70,7 @@ pass -class CPythonExceptionPolicy(ExceptionPolicy): #uses issubclass() and llvm invoke&unwind +class InvokeUnwindExceptionPolicy(ExceptionPolicy): #uses issubclass() and llvm invoke&unwind def __init__(self): pass @@ -160,7 +160,7 @@ return '-enable-correct-eh-support' -class FastExceptionPolicy(ExceptionPolicy): #uses issubclass() and last_exception tests after each call +class ExplicitExceptionPolicy(ExceptionPolicy): #uses issubclass() and last_exception tests after each call def __init__(self): self.invoke_count = 0 @@ -205,7 +205,8 @@ def invoke(self, codewriter, targetvar, tail_, cconv, returntype, functionref, args, label, except_label): if returntype == 'void': - codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args)) + if functionref != '%keepalive': #XXX I think keepalive should not be the last operation here! + codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args)) else: codewriter.indent('%s = %scall %s %s %s(%s)' % (targetvar, tail_, cconv, returntype, functionref, args)) tmp = '%%invoke.tmp.%d' % self.invoke_count Modified: pypy/dist/pypy/translator/js/gc.py ============================================================================== --- pypy/dist/pypy/translator/js/gc.py (original) +++ pypy/dist/pypy/translator/js/gc.py Fri Oct 7 12:07:58 2005 @@ -1,8 +1,5 @@ -import py -from pypy.tool.ansi_print import ansi_log -log = py.log.Producer("llvm") -log.setconsumer("llvm", ansi_log) - +from pypy.translator.js.log import log +log = log.gc class GcPolicy: def __init__(self): @@ -27,7 +24,7 @@ from os.path import exists boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') if gcpolicy == 'boehm' and not boehm_on_path: - log.gc.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc') + log.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc') gcpolicy = 'none' if gcpolicy == 'boehm': Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Fri Oct 7 12:07:58 2005 @@ -13,32 +13,20 @@ import py -#from pypy.translator.llvm import build_llvm_module from pypy.translator.llvm.database import Database -#from pypy.translator.llvm.pyxwrapper import write_pyx_wrapper from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir -from pypy.translator.llvm.codewriter import CodeWriter -#from pypy.translator.llvm.codewriter import , DEFAULT_TAIL, DEFAULT_CCONV -#from pypy.translator.llvm import extfuncnode -#from pypy.translator.llvm.module.extfunction import extdeclarations, extfunctions, dependencies -#from pypy.translator.llvm.node import JSNode -#from pypy.translator.llvm.structnode import StructNode -#from pypy.translator.llvm.externs2ll import post_setup_externs, generate_llfile -from pypy.translator.llvm.gc import GcPolicy -from pypy.translator.llvm.exception import ExceptionPolicy -#from pypy.translator.translator import Translator - +from pypy.translator.js.codewriter import CodeWriter +from pypy.translator.js.gc import GcPolicy +from pypy.translator.js.exception import ExceptionPolicy from pypy.translator.js.log import log -function_count = {} -#llexterns_header = llexterns_functions = None - class JS(object): # JS = Javascript - - def __init__(self, translator, func=None, gcpolicy=None, exceptionpolicy=None, debug=False): + function_count = {} + + def __init__(self, translator, function=None, gcpolicy=None, exceptionpolicy=None, debug=False): self.db = Database(self, translator) self.translator = translator self.gcpolicy = GcPolicy.new(gcpolicy) @@ -48,10 +36,14 @@ if debug: translator.checkgraphs() - if func is None: - func = self.translator.entrypoint - self.entrypoint = func + if function is None: + function= self.translator.entrypoint + self.entrypoint = function + self.filename = self.wrapper_filename = None + + def write_source(self): + func = self.entrypoint ptr = getfunctionptr(self.translator, func) c = inputconst(lltype.typeOf(ptr), ptr) entry_point = c.value._obj @@ -78,14 +70,14 @@ # llexterns_header, llexterns_functions = generate_llfile(self.db, extern_decls, support_functions, self.debug) # 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 + if func.func_name in self.function_count: + postfix = '_%d' % self.function_count[func.func_name] + self.function_count[func.func_name] += 1 else: postfix = '' - function_count[func.func_name] = 1 - filename = udir.join(func.func_name + postfix).new(ext='.js') - f = open(str(filename),'w') + self.function_count[func.func_name] = 1 + self.filename = udir.join(func.func_name + postfix).new(ext='.js') + f = open(str(self.filename),'w') codewriter = CodeWriter(f, self) comment = codewriter.comment nl = codewriter.newline @@ -148,5 +140,13 @@ # nl(); comment("External Function Implementation") ; nl() # codewriter.append(llexterns_functions) + comment("Wrapper code for the Javascript CLI") ; nl() + graph = self.db.entrynode.graph + startblock = graph.startblock + args = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)]) + wrappercode = 'pypy_%s(%s);\n' % (graph.name, args) + codewriter.indent(wrappercode) + comment("End of file") ; nl() - self.filename = filename + log('Written:', self.filename) + return self.filename Modified: pypy/dist/pypy/translator/js/log.py ============================================================================== --- pypy/dist/pypy/translator/js/log.py (original) +++ pypy/dist/pypy/translator/js/log.py Fri Oct 7 12:07:58 2005 @@ -1,4 +1,4 @@ import py from pypy.tool.ansi_print import ansi_log log = py.log.Producer("js") -log.setconsumer("js", ansi_log) +py.log.setconsumer("js", ansi_log) Modified: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/runtest.py (original) +++ pypy/dist/pypy/translator/js/test/runtest.py Fri Oct 7 12:07:58 2005 @@ -12,38 +12,26 @@ return False return True -def write_wrapper(js_filename): - jswrapper_filename = js_filename.new(ext='_wrapper.js') - f = open(str(jswrapper_filename), 'w') - f.write('print(42);\n') - f.close() - log('Written:', jswrapper_filename) - return jswrapper_filename +class compile_function(object): + def __init__(self, function, annotation, view=False): + if not _CLI_is_on_path(): + py.test.skip('Javascript CLI (js) not found') -class jscallable(object): - def __init__(self, jswrapper_filename): - self.jswrapper_filename = jswrapper_filename - - def __call__(self): - cmd = 'js "%s"' % str(self.jswrapper_filename) - s = os.popen(cmd).read() - e = eval(s) - return e - -def compile(function, annotation=[], view=False): - if not _CLI_is_on_path(): - py.test.skip('Javascript CLI (js) not found') - - t = Translator(function) - a = t.annotate(annotation) - a.simplify() - t.specialize() - t.backend_optimizations() - if view: - t.view() + t = Translator(function) + a = t.annotate(annotation) + a.simplify() + t.specialize() + t.backend_optimizations() + if view: + t.view() + self.js = JS(t, function) + self.js.write_source() - js = JS(t, function) - log('Written:', js.filename) - - jswrapper_filename = write_wrapper(js.filename) - return jscallable(jswrapper_filename) + def __call__(self, *kwds): + #note: lowercase string for (py)False->(js)false, etc. + args = ' '.join([str(kw).lower() for kw in kwds]) + cmd = 'js %s %s' % (self.js.filename, args) + log(cmd) + s = os.popen(cmd).read() + res = eval(s) + return res From pedronis at codespeak.net Fri Oct 7 12:35:15 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 7 Oct 2005 12:35:15 +0200 (CEST) Subject: [pypy-svn] r18257 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051007103515.066AF27B56@code1.codespeak.net> Author: pedronis Date: Fri Oct 7 12:35:14 2005 New Revision: 18257 Modified: pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/c/test/test_genc.py Log: spell infinity as HUGE_VAL (Py_HUGE_VAL for now precisely) Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Fri Oct 7 12:35:14 2005 @@ -20,13 +20,10 @@ 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 '(1E200*1E200)' + return '(Py_HUGE_VAL)' else: - return '(-1E200*1E200)' + return '(-Py_HUGE_VAL)' else: return repr(value) 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 Fri Oct 7 12:35:14 2005 @@ -211,6 +211,11 @@ f1 = compile(fn, []) res = f1() assert res > 0 and res == res / 2 + def fn(): + return -x + f1 = compile(fn, []) + res = f1() + assert res < 0 and res == res / 2 def test_x(): From arigo at codespeak.net Fri Oct 7 13:10:33 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 7 Oct 2005 13:10:33 +0200 (CEST) Subject: [pypy-svn] r18258 - pypy/dist/pypy/translator/c/test Message-ID: <20051007111033.A7CBD27B56@code1.codespeak.net> Author: arigo Date: Fri Oct 7 13:10:30 2005 New Revision: 18258 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Trying to sanitize the tests about env vars. 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 Oct 7 13:10:30 2005 @@ -431,29 +431,36 @@ f1(dirname, True) assert not os.path.exists(dirname) +# ____________________________________________________________ + +def _real_getenv(var): + cmd = '''python -c "import os; x=os.environ.get('%s'); print (x is None) and 'F' or ('T'+x)"''' % var + g = os.popen(cmd, 'r') + output = g.read().strip() + g.close() + if output == 'F': + return None + elif output.startswith('T'): + return output[1:] + else: + raise ValueError, 'probing for env var returned %r' % (output,) + +def _real_envkeys(): + cmd = '''python -c "import os; print os.environ.keys()"''' + g = os.popen(cmd, 'r') + output = g.read().strip() + g.close() + if output.startswith('[') and output.endswith(']'): + return eval(output) + else: + raise ValueError, 'probing for all env vars returned %r' % (output,) + 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) - - -# 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 - + assert _real_getenv('abcdefgh') == '12345678' def test_environ(): def env(idx): @@ -463,25 +470,16 @@ return False return ret func = compile(env, [int]) - count = 0 + keys = [] while 1: - if not func(count): + s = func(len(keys)) + if not s: break - count += 1 - 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() + keys.append(s) + expected = _real_envkeys() + keys.sort() + expected.sort() + return keys == expected posix = __import__(os.name) if hasattr(posix, "unsetenv"): @@ -490,10 +488,8 @@ 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 + assert _real_getenv('ABCDEF') == 'a' f() - cmd = '''python -c "import os, sys; sys.exit(os.getenv('ABCDEF') != None)"''' - assert os.system(cmd) == 0 + assert _real_getenv('ABCDEF') is None f() - assert os.system(cmd) == 0 + assert _real_getenv('ABCDEF') is None From ericvrp at codespeak.net Fri Oct 7 17:32:12 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 7 Oct 2005 17:32:12 +0200 (CEST) Subject: [pypy-svn] r18263 - pypy/dist/pypy/translator/js Message-ID: <20051007153212.703EC27B54@code1.codespeak.net> Author: ericvrp Date: Fri Oct 7 17:32:10 2005 New Revision: 18263 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/exception.py pypy/dist/pypy/translator/js/extfuncnode.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/gc.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/opaquenode.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py Log: More things working, but no working tests yet. The file looks javascript-ish. The cast are probably incorrect and there are no globals/pbc's yet. We are able to add two numbers though! Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Fri Oct 7 17:32:10 2005 @@ -1,8 +1,8 @@ import py from pypy.rpython import lltype -from pypy.translator.llvm.log import log -from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode -from pypy.translator.llvm import varsize +from pypy.translator.js.node import LLVMNode, ConstantLLVMNode +from pypy.translator.js import varsize +from pypy.translator.js.log import log log = log.structnode class ArrayTypeNode(LLVMNode): Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Fri Oct 7 17:32:10 2005 @@ -1,144 +1,173 @@ import py from itertools import count -from pypy.translator.llvm.log import log +from pypy.translator.js.log import log log = log.codewriter -DEFAULT_TAIL = '' #/tail -DEFAULT_CCONV = 'fastcc' #ccc/fastcc - class CodeWriter(object): - def __init__(self, f, genllvm): + + tabstring = ' ' + + def __init__(self, f, js): self.f = f - self.genllvm = genllvm - self.word = genllvm.db.get_machine_word() - self.uword = genllvm.db.get_machine_uword() - - def append(self, line): - self.f.write(line + '\n') - - def comment(self, line, indent=True): - line = "// " + line - if indent: - self.indent(line) + self.js = js + + def append(self, line, indentation_level=4): + if indentation_level: + s = self.tabstring * indentation_level else: - self.append(line) + s = '' + self.f.write(s + line + '\n') + + def comment(self, line, indentation_level=4): + self.append("// " + line, indentation_level) + + def llvm(self, line, indentation_level=4): + self.comment("LLVM " + line, indentation_level) def newline(self): self.append("") - def indent(self, line): - self.append(" " + line) - def label(self, name): - self.newline() - self.append("// QQQ %s:" % name) + self.append("case %d:" % name, 3) + openblock = label + + def closeblock(self): + self.append('break') def globalinstance(self, name, typeandata): - self.append("// QQQ %s = %s global %s" % (name, "internal", typeandata)) + self.llvm("%s = %s global %s" % (name, "internal", typeandata)) def structdef(self, name, typereprs): - self.append("// QQQ %s = type { %s }" %(name, ", ".join(typereprs))) + self.llvm("%s = type { %s }" %(name, ", ".join(typereprs))) def arraydef(self, name, lentype, typerepr): - self.append("// QQQ %s = type { %s, [0 x %s] }" % (name, lentype, typerepr)) + self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr)) def funcdef(self, name, rettyperepr, argtypereprs): - self.append("// QQQ %s = type %s (%s)" % (name, rettyperepr, + self.llvm("%s = type %s (%s)" % (name, rettyperepr, ", ".join(argtypereprs))) - def declare(self, decl, cconv=DEFAULT_CCONV): - self.append("// QQQ declare %s %s" %(cconv, decl,)) + def declare(self, decl): + #self.llvm("declare %s" % decl, 0) + pass def startimpl(self): - self.newline() - self.append("// QQQ implementation") - self.newline() + #self.llvm("implementation", 0) + pass def br_uncond(self, blockname): - self.indent("// QQQ br label %%%s" %(blockname,)) + self.append('prevblock = block') + self.append('block = %d' % blockname) + #self.llvm("br label %s" %(blockname,)) def br(self, cond, blockname_false, blockname_true): - self.indent("// QQQ br bool %s, label %%%s, label %%%s" + self.llvm("br bool %s, label %s, label %s" % (cond, blockname_true, blockname_false)) def switch(self, intty, cond, defaultdest, value_label): labels = '' for value, label in value_label: - labels += ' %s %s, label %%%s' % (intty, value, label) - self.indent("// QQQ switch %s %s, label %%%s [%s ]" + labels += ' %s %s, label %s' % (intty, value, label) + self.llvm("switch %s %s, label %s [%s ]" % (intty, cond, defaultdest, labels)) - def openfunc(self, decl, is_entrynode=False, cconv=DEFAULT_CCONV): + def openfunc(self, funcnode, blocks): + self.funcnode = funcnode + self.blocks = blocks + usedvars = {} #XXX could probably be limited to inputvars + for block in blocks: + for op in block.operations: + targetvar = self.js.db.repr_arg(op.result) + usedvars[targetvar] = True self.newline() - self.append("%s {" % decl) + self.append("function %s {" % self.funcnode.getdecl(), 0) + self.append("var %s" % ' = 0, '.join(usedvars.keys()), 1) + self.append("var block = 0", 1) + self.append("while (block != undefined) {", 1) + self.append("switch (block) {", 2) def closefunc(self): - self.append("}") + self.append("} // end of switch (block)", 2) + self.append("} // end of while (block != undefined)", 1) + self.append("} // end of function %s" % self.funcnode.getdecl(), 0) def ret(self, type_, ref): - if type_ == '// QQQ void': - self.indent("// QQQ ret void") + if type_ == 'void': + self.append("return") else: - self.indent("// QQQ ret %s %s" % (type_, ref)) + self.append("return " + ref) def phi(self, targetvar, type_, refs, blocknames): - assert targetvar.startswith('%') assert refs and len(refs) == len(blocknames), "phi node requires blocks" mergelist = ", ".join( - ["[%s, %%%s]" % item + ["[%s, %s]" % item for item in zip(refs, blocknames)]) s = "%s = phi %s %s" % (targetvar, type_, mergelist) - self.indent('// QQQ ' + s) + self.llvm(s) + self.append('switch (prevblock) {') + for i, blockname in enumerate(blocknames): + self.append('case %d: %s = %s; break' % (blockname, targetvar, refs[i]), 5) + self.append('} // end of switch (prevblock)') def binaryop(self, name, targetvar, type_, ref1, ref2): - self.indent("// QQQ %s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) + self.llvm("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) + conv = { 'mul':'*', 'add':'+', 'sub':'-', 'div':'/' } + if name in conv: + c = conv[name] + self.append("%(targetvar)s = %(ref1)s %(c)s %(ref2)s" % locals()) + else: + self.append("TODO: binaryop") def shiftop(self, name, targetvar, type_, ref1, ref2): - self.indent("// QQQ %s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) + self.llvm("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) - def call(self, targetvar, returntype, functionref, argrefs, argtypes, label=None, except_label=None, tail=DEFAULT_TAIL, cconv=DEFAULT_CCONV): - if cconv is not 'fastcc': - tail_ = '' - else: - tail_ = tail - if tail_: - tail_ += ' ' + def call(self, targetvar, returntype, functionref, argrefs, argtypes, label=None, except_label=None): args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) if except_label: - self.genllvm.exceptionpolicy.invoke(self, targetvar, tail_, cconv, returntype, functionref, args, label, except_label) + self.js.exceptionpolicy.invoke(self, targetvar, returntype, functionref, args, label, except_label) else: if returntype == 'void': - self.indent("// QQQ call void %s(%s)" % (functionref, args)) + self.llvm("call void %s(%s)" % (functionref, args)) else: - self.indent("// QQQ %s = call %s %s(%s)" % (targetvar, returntype, functionref, args)) + self.llvm("%s = call %s %s(%s)" % (targetvar, returntype, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): if fromtype == 'void' and targettype == 'void': return - self.indent("// QQQ %(targetvar)s = cast %(fromtype)s " + self.llvm("%(targetvar)s = cast %(fromtype)s " "%(fromvar)s to %(targettype)s" % locals()) + if targettype == fromtype: + self.append("%(targetvar)s = %(fromvar)s%(convfunc)s" % locals()) + elif targettype in ('int','uint',): + self.append("%(targetvar)s = 0 + %(fromvar)s" % locals()) + elif targettype in ('double',): + self.append("%(targetvar)s = 0.0 + %(fromvar)s" % locals()) + elif targettype in ('bool',): + self.append("%(targetvar)s = %(fromvar)s == 0" % locals()) + else: + self.append("// TODO %(targetvar)s = %(fromvar)s...()" % locals()) - def malloc(self, targetvar, type_, size=1, atomic=False, cconv=DEFAULT_CCONV): - for s in self.genllvm.gcpolicy.malloc(targetvar, type_, size, atomic, self.word, self.uword).split('\n'): - self.indent('// QQQ ' + s) + def malloc(self, targetvar, type_, size=1, atomic=False): + for s in self.js.gcpolicy.malloc(targetvar, type_, size, atomic, 'word', 'uword').split('\n'): + self.llvm(s) def getelementptr(self, targetvar, type, typevar, *indices): 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('// QQQ ' + res) + self.llvm(res) def load(self, targetvar, targettype, ptr): - self.indent("// QQQ %(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) + self.llvm("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) def store(self, valuetype, valuevar, ptr): - self.indent("// QQQ store %(valuetype)s %(valuevar)s, " + self.llvm("store %(valuetype)s %(valuevar)s, " "%(valuetype)s* %(ptr)s" % locals()) def debugcomment(self, tempname, len, tmpname): word = self.word - res = "%s = 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('// QQQ ' + res) + self.llvm(res) Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Fri Oct 7 17:32:10 2005 @@ -1,17 +1,17 @@ import sys -from pypy.translator.llvm.log import log -from pypy.translator.llvm.funcnode import FuncNode, FuncTypeNode -from pypy.translator.llvm.extfuncnode import ExternalFuncNode -from pypy.translator.llvm.structnode import StructNode, StructVarsizeNode, \ +from pypy.translator.js.funcnode import FuncNode, FuncTypeNode +from pypy.translator.js.extfuncnode import ExternalFuncNode +from pypy.translator.js.structnode import StructNode, StructVarsizeNode, \ StructTypeNode, StructVarsizeTypeNode -from pypy.translator.llvm.arraynode import ArrayNode, StrArrayNode, \ +from pypy.translator.js.arraynode import ArrayNode, StrArrayNode, \ VoidArrayNode, ArrayTypeNode, VoidArrayTypeNode -from pypy.translator.llvm.opaquenode import OpaqueNode, OpaqueTypeNode -from pypy.translator.llvm.node import ConstantLLVMNode +from pypy.translator.js.opaquenode import OpaqueNode, OpaqueTypeNode +from pypy.translator.js.node import ConstantLLVMNode from pypy.rpython import lltype from pypy.objspace.flow.model import Constant, Variable +from pypy.translator.js.log import log log = log.database @@ -245,7 +245,7 @@ return node.get_ref() else: assert isinstance(arg, Variable) - return "%" + str(arg) + return str(arg) def repr_arg_type(self, arg): assert isinstance(arg, (Constant, Variable)) @@ -300,7 +300,7 @@ def repr_tmpvar(self): count = self._tmpcount self._tmpcount += 1 - return "%tmp." + str(count) + return "tmp_" + str(count) def repr_constructor(self, type_): return self.obj2node[type_].constructor_ref Modified: pypy/dist/pypy/translator/js/exception.py ============================================================================== --- pypy/dist/pypy/translator/js/exception.py (original) +++ pypy/dist/pypy/translator/js/exception.py Fri Oct 7 17:32:10 2005 @@ -1,6 +1,3 @@ -from pypy.translator.llvm.codewriter import DEFAULT_CCONV - - class ExceptionPolicy: RINGBUGGER_SIZE = 8192 RINGBUFFER_ENTRY_MAXSIZE = 16 @@ -51,13 +48,13 @@ def new(exceptionpolicy=None): #factory exceptionpolicy = exceptionpolicy or 'explicit' if exceptionpolicy == 'invokeunwind': - from pypy.translator.llvm.exception import InvokeUnwindExceptionPolicy + from pypy.translator.js.exception import InvokeUnwindExceptionPolicy exceptionpolicy = InvokeUnwindExceptionPolicy() elif exceptionpolicy == 'explicit': - from pypy.translator.llvm.exception import ExplicitExceptionPolicy + from pypy.translator.js.exception import ExplicitExceptionPolicy exceptionpolicy = ExplicitExceptionPolicy() elif exceptionpolicy == 'none': - from pypy.translator.llvm.exception import NoneExceptionPolicy + from pypy.translator.js.exception import NoneExceptionPolicy exceptionpolicy = NoneExceptionPolicy() else: raise Exception, 'unknown exceptionpolicy: ' + str(exceptionpolicy) @@ -77,10 +74,9 @@ def llvmcode(self, entrynode): returntype, entrypointname = entrynode.getdecl().split('%', 1) noresult = self._noresult(returntype) - cconv = DEFAULT_CCONV return ''' ccc %(returntype)s%%__entrypoint__%(entrypointname)s { - %%result = invoke %(cconv)s %(returntype)s%%%(entrypointname)s to label %%no_exception except label %%exception + %%result = invoke %(returntype)s%%%(entrypointname)s to label %%no_exception except label %%exception no_exception: store %%RPYTHON_EXCEPTION_VTABLE* null, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type @@ -101,12 +97,12 @@ } ''' % locals() + self.RINGBUFFER_LLVMCODE - def invoke(self, codewriter, targetvar, tail_, cconv, returntype, functionref, args, label, except_label): + def invoke(self, codewriter, targetvar, returntype, functionref, args, label, except_label): labels = 'to label %%%s except label %%%s' % (label, except_label) if returntype == 'void': - codewriter.indent('%sinvoke %s void %s(%s) %s' % (tail_, cconv, functionref, args, labels)) + codewriter.llvm('invoke void %s(%s) %s' % (functionref, args, labels)) else: - codewriter.indent('%s = %sinvoke %s %s %s(%s) %s' % (targetvar, tail_, cconv, returntype, functionref, args, labels)) + codewriter.llvm('%s = invoke %s %s(%s) %s' % (targetvar, returntype, functionref, args, labels)) def _is_raise_new_exception(self, db, graph, block): from pypy.objspace.flow.model import mkentrymap @@ -141,7 +137,7 @@ #Which is already stored in the global variables. #So nothing needs to happen here! - codewriter.indent('unwind') + codewriter.llvm('unwind') def fetch_exceptions(self, codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value): for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: @@ -154,7 +150,7 @@ def reraise(self, funcnode, codewriter): codewriter.comment('reraise when exception is not caught') - codewriter.indent('unwind') + codewriter.llvm('unwind') def llc_options(self): return '-enable-correct-eh-support' @@ -167,11 +163,10 @@ def llvmcode(self, entrynode): returntype, entrypointname = entrynode.getdecl().split('%', 1) noresult = self._noresult(returntype) - cconv = DEFAULT_CCONV return ''' ccc %(returntype)s%%__entrypoint__%(entrypointname)s { store %%RPYTHON_EXCEPTION_VTABLE* null, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type - %%result = call %(cconv)s %(returntype)s%%%(entrypointname)s + %%result = call %(returntype)s%%%(entrypointname)s %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type %%exc = seteq %%RPYTHON_EXCEPTION_VTABLE* %%tmp, null br bool %%exc, label %%no_exception, label %%exception @@ -203,18 +198,18 @@ create_exception_handling(translator, graph) #translator.view() - def invoke(self, codewriter, targetvar, tail_, cconv, returntype, functionref, args, label, except_label): + def invoke(self, codewriter, targetvar, returntype, functionref, args, label, except_label): if returntype == 'void': if functionref != '%keepalive': #XXX I think keepalive should not be the last operation here! - codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args)) + codewriter.append('call void %s(%s)' % (functionref, args)) else: - codewriter.indent('%s = %scall %s %s %s(%s)' % (targetvar, tail_, cconv, returntype, functionref, args)) + codewriter.llvm('%s = call %s %s(%s)' % (targetvar, returntype, functionref, args)) tmp = '%%invoke.tmp.%d' % self.invoke_count exc = '%%invoke.exc.%d' % self.invoke_count self.invoke_count += 1 - codewriter.indent('%(tmp)s = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type' % locals()) - codewriter.indent('%(exc)s = seteq %%RPYTHON_EXCEPTION_VTABLE* %(tmp)s, null' % locals()) - codewriter.indent('br bool %(exc)s, label %%%(label)s, label %%%(except_label)s' % locals()) + codewriter.llvm('%(tmp)s = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type' % locals()) + codewriter.llvm('%(exc)s = seteq %%RPYTHON_EXCEPTION_VTABLE* %(tmp)s, null' % locals()) + codewriter.llvm('br bool %(exc)s, label %%%(label)s, label %%%(except_label)s' % locals()) def write_exceptblock(self, funcnode, codewriter, block): assert len(block.inputargs) == 2 @@ -228,7 +223,7 @@ codewriter.store(inputargtypes[0], inputargs[0], '%last_exception_type') codewriter.store(inputargtypes[1], inputargs[1], '%last_exception_value') - codewriter.indent('ret ' + noresult) + codewriter.llvm('ret ' + noresult) def fetch_exceptions(self, codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value): for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: @@ -243,7 +238,7 @@ def reraise(self, funcnode, codewriter): noresult = self._nonoderesult(funcnode) - codewriter.indent('ret ' + noresult) + codewriter.llvm('ret ' + noresult) def llc_options(self): return '' Modified: pypy/dist/pypy/translator/js/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/js/extfuncnode.py (original) +++ pypy/dist/pypy/translator/js/extfuncnode.py Fri Oct 7 17:32:10 2005 @@ -1,6 +1,6 @@ import py -from pypy.translator.llvm.node import ConstantLLVMNode -from pypy.translator.llvm.log import log +from pypy.translator.js.node import ConstantLLVMNode +from pypy.translator.js.log import log log = log.extfuncnode class ExternalFuncNode(ConstantLLVMNode): Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Fri Oct 7 17:32:10 2005 @@ -3,12 +3,12 @@ from pypy.objspace.flow.model import Block, Constant, Variable, Link from pypy.objspace.flow.model import flatten, mkentrymap, traverse, last_exception from pypy.rpython import lltype -from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode -from pypy.translator.llvm.opwriter import OpWriter -from pypy.translator.llvm.log import log -from pypy.translator.llvm.backendopt.removeexcmallocs import remove_exception_mallocs -from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs +from pypy.translator.js.node import LLVMNode, ConstantLLVMNode +from pypy.translator.js.opwriter import OpWriter +#from pypy.translator.js.backendopt.removeexcmallocs import remove_exception_mallocs +#from pypy.translator.js.backendopt.mergemallocs import merge_mallocs from pypy.translator.unsimplify import remove_double_links +from pypy.translator.js.log import log log = log.funcnode class FuncTypeNode(LLVMNode): @@ -33,16 +33,16 @@ codewriter.funcdef(self.ref, returntype, inputargtypes) class FuncNode(ConstantLLVMNode): - __slots__ = "db value ref graph block_to_name".split() + __slots__ = "db value ref graph blockindex".split() 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 self.db.genllvm.exceptionpolicy.transform(self.db.translator, self.graph) - remove_exception_mallocs(self.db.translator, self.graph, self.ref) + #remove_exception_mallocs(self.db.translator, self.graph, self.ref) #merge_mallocs(self.db.translator, self.graph, self.ref) remove_double_links(self.db.translator, self.graph) @@ -78,21 +78,22 @@ def writeimpl(self, codewriter): graph = self.graph log.writeimpl(graph.name) - 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)] - self.block_to_name = {} - for i, block in enumerate(l): - self.block_to_name[block] = "block%s" % i - for block in l: - codewriter.label(self.block_to_name[block]) + blocks = [x for x in flatten(graph) if isinstance(x, Block)] + self.blockindex= {} + for i, block in enumerate(blocks): + self.blockindex[block] = i + codewriter.openfunc(self, blocks) + for block in blocks: + codewriter.openblock(self.blockindex[block]) for name in 'startblock returnblock exceptblock'.split(): if block is getattr(graph, name): getattr(self, 'write_' + name)(codewriter, block) break else: self.write_block(codewriter, block) + codewriter.closeblock() codewriter.closefunc() def writecomments(self, codewriter): @@ -134,10 +135,10 @@ inputargs = self.db.repr_arg_multi(startblock_inputargs) inputargtypes = self.db.repr_arg_type_multi(startblock_inputargs) returntype = self.db.repr_arg_type(self.graph.returnblock.inputargs[0]) - result = "%s %s" % (returntype, self.ref) - args = ["%s %s" % item for item in zip(inputargtypes, inputargs)] - result += "(%s)" % ", ".join(args) - return result + #result = "%s %s" % (returntype, self.ref) + #args = ["%s %s" % item for item in zip(inputargtypes, inputargs)] + #result += "(%s)" % ", ".join(args) + return self.ref + "(%s)" % ", ".join(inputargs) def write_block(self, codewriter, block): self.write_block_phi_nodes(codewriter, block) @@ -152,12 +153,11 @@ inputargtypes = self.db.repr_arg_type_multi(block.inputargs) for i, (arg, type_) in enumerate(zip(inputargs, inputargtypes)): names = self.db.repr_arg_multi([link.args[i] for link in entrylinks]) - blocknames = [self.block_to_name[link.prevblock] - for link in entrylinks] + blocknames = [self.blockindex[link.prevblock] for link in entrylinks] for i, link in enumerate(entrylinks): #XXX refactor into a transformation if link.prevblock.exitswitch == Constant(last_exception) and \ link.prevblock.exits[0].target != block: - blocknames[i] += '_exception_found_branchto_' + self.block_to_name[block] + blocknames[i] += '_exception_found_branchto_' + self.blockindex[block] data.append( (arg, type_, names, blocknames) ) return data @@ -172,11 +172,11 @@ #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]) + codewriter.br_uncond(self.blockindex[block.exits[0].target]) elif len(block.exits) == 2: cond = self.db.repr_arg(block.exitswitch) - codewriter.br(cond, self.block_to_name[block.exits[0].target], - self.block_to_name[block.exits[1].target]) + codewriter.br(cond, self.blockindex[block.exits[0].target], + self.blockindex[block.exits[1].target]) def write_block_operations(self, codewriter, block): opwriter = OpWriter(self.db, codewriter, self, block) Modified: pypy/dist/pypy/translator/js/gc.py ============================================================================== --- pypy/dist/pypy/translator/js/gc.py (original) +++ pypy/dist/pypy/translator/js/gc.py Fri Oct 7 17:32:10 2005 @@ -28,13 +28,13 @@ gcpolicy = 'none' if gcpolicy == 'boehm': - from pypy.translator.llvm.gc import BoehmGcPolicy + from pypy.translator.js.gc import BoehmGcPolicy gcpolicy = BoehmGcPolicy() elif gcpolicy == 'ref': - from pypy.translator.llvm.gc import RefcountingGcPolicy + from pypy.translator.js.gc import RefcountingGcPolicy gcpolicy = RefcountingGcPolicy() elif gcpolicy == 'none': - from pypy.translator.llvm.gc import NoneGcPolicy + from pypy.translator.js.gc import NoneGcPolicy gcpolicy = NoneGcPolicy() else: raise Exception, 'unknown gcpolicy: ' + str(gcpolicy) Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Fri Oct 7 17:32:10 2005 @@ -3,7 +3,7 @@ http://webreference.com/javascript/reference/core_ref/ http://webreference.com/programming/javascript/ http://mochikit.com/ - + http://www.mozilla.org/js/spidermonkey/ ''' #import os @@ -13,10 +13,10 @@ import py -from pypy.translator.llvm.database import Database from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir +from pypy.translator.js.database import Database from pypy.translator.js.codewriter import CodeWriter from pypy.translator.js.gc import GcPolicy from pypy.translator.js.exception import ExceptionPolicy @@ -51,8 +51,8 @@ # set up all nodes self.db.setup_all() - self.entrynode = self.db.set_entrynode(entry_point) - entryfunc_name = self.entrynode.getdecl().split('%', 1)[1].split('(')[0] + #self.entrynode = self.db.set_entrynode(entry_point) + #entryfunc_name = self.entrynode.getdecl().split('%', 1)[1].split('(')[0] ## post set up externs #extern_decls = post_setup_externs(self.db) @@ -79,14 +79,12 @@ self.filename = udir.join(func.func_name + postfix).new(ext='.js') f = open(str(self.filename),'w') codewriter = CodeWriter(f, self) - comment = codewriter.comment - nl = codewriter.newline #if using_external_functions: - # nl(); comment("External Function Declarations") ; nl() + # codewriter.comment("External Function Declarations") # codewriter.append(llexterns_header) - nl(); comment("Type Declarations"); nl() + codewriter.comment("Type Declarations", 0) #for c_name, obj in extern_decls: # if isinstance(obj, lltype.LowLevelType): # if isinstance(obj, lltype.Ptr): @@ -97,18 +95,18 @@ for typ_decl in self.db.getnodes(): typ_decl.writedatatypedecl(codewriter) - nl(); comment("Global Data") ; nl() + codewriter.comment("Global Data", 0) for typ_decl in self.db.getnodes(): typ_decl.writeglobalconstants(codewriter) - nl(); comment("Function Prototypes") ; nl() + codewriter.comment("Function Prototypes", 0) #codewriter.append(extdeclarations) #codewriter.append(self.gcpolicy.declarations()) for typ_decl in self.db.getnodes(): typ_decl.writedecl(codewriter) - nl(); comment("Function Implementation") + codewriter.comment("Function Implementation", 0) codewriter.startimpl() for typ_decl in self.db.getnodes(): @@ -137,16 +135,18 @@ # depdone[dep] = True # #if using_external_functions: - # nl(); comment("External Function Implementation") ; nl() + # codewriter.comment("External Function Implementation", 0) # codewriter.append(llexterns_functions) - comment("Wrapper code for the Javascript CLI") ; nl() - graph = self.db.entrynode.graph + codewriter.newline() + codewriter.comment("Wrapper code for the Javascript CLI", 0) + codewriter.newline() + graph = self.db.obj2node[entry_point].graph startblock = graph.startblock args = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)]) - wrappercode = 'pypy_%s(%s);\n' % (graph.name, args) - codewriter.indent(wrappercode) - - comment("End of file") ; nl() + wrappercode = 'print(pypy_%s(%s))' % (graph.name, args) + codewriter.append(wrappercode, 0) + codewriter.newline() + codewriter.comment("EOF", 0) log('Written:', self.filename) return self.filename Modified: pypy/dist/pypy/translator/js/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/js/opaquenode.py (original) +++ pypy/dist/pypy/translator/js/opaquenode.py Fri Oct 7 17:32:10 2005 @@ -1,4 +1,4 @@ -from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode +from pypy.translator.js.node import LLVMNode, ConstantLLVMNode from pypy.rpython import lltype class OpaqueTypeNode(LLVMNode): Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Fri Oct 7 17:32:10 2005 @@ -1,9 +1,9 @@ import py from pypy.objspace.flow.model import Constant from pypy.rpython import lltype -from pypy.translator.llvm.module.extfunction import extfunctions -from pypy.translator.llvm.extfuncnode import ExternalFuncNode -from pypy.translator.llvm.log import log +#from pypy.translator.js.module.extfunction import extfunctions +from pypy.translator.js.extfuncnode import ExternalFuncNode +from pypy.translator.js.log import log log = log.opwriter class OpWriter(object): @@ -286,8 +286,8 @@ def last_exception_type_ptr(self, op): e = self.db.translator.rtyper.getexceptiondata() - lltype_of_exception_type = ('%structtype.' + e.lltype_of_exception_type.TO.__name__ + '*') - self.codewriter.load('%'+str(op.result), lltype_of_exception_type, '%last_exception_type') + lltype_of_exception_type = ('structtype.' + e.lltype_of_exception_type.TO.__name__ + '*') + self.codewriter.load('%'+str(op.result), lltype_of_exception_type, 'last_exception_type') def invoke(self, op): op_args = [arg for arg in op.args @@ -319,8 +319,8 @@ argrefs = self.db.repr_arg_multi(op_args[1:]) argtypes = self.db.repr_arg_type_multi(op_args[1:]) - none_label = self.node.block_to_name[link.target] - block_label = self.node.block_to_name[self.block] + none_label = self.node.blockindex[link.target] + block_label = self.node.blockindex[self.block] exc_label = block_label + '_exception_handling' if self.db.is_function_ptr(op.result): #use longhand form @@ -329,11 +329,11 @@ argtypes, none_label, exc_label) e = self.db.translator.rtyper.getexceptiondata() - ll_exception_match = '%pypy_' + e.ll_exception_match.__name__ - lltype_of_exception_type = ('%structtype.' + + ll_exception_match = 'pypy_' + e.ll_exception_match.__name__ + lltype_of_exception_type = ('structtype.' + e.lltype_of_exception_type.TO.__name__ + '*') - lltype_of_exception_value = ('%structtype.' + + lltype_of_exception_value = ('structtype.' + e.lltype_of_exception_value.TO.__name__ + '*') @@ -346,7 +346,7 @@ etype = self.db.obj2node[link.llexitcase._obj] current_exception_type = etype.get_ref() - target = self.node.block_to_name[link.target] + target = self.node.blockindex[link.target] exc_found_label = block_label + '_exception_found_branchto_' + target last_exc_type_var, last_exc_value_var = None, None @@ -355,9 +355,9 @@ for name, blockname in zip(names, blocknames): if blockname != exc_found_label: continue - if name.startswith('%last_exception_'): + if name.startswith('last_exception_'): last_exc_type_var = name - if name.startswith('%last_exc_value_'): + if name.startswith('last_exc_value_'): last_exc_value_var = name t = (exc_found_label,target,last_exc_type_var,last_exc_value_var) @@ -371,7 +371,7 @@ else: #catch specific exception (class) type if not last_exception_type: #load pointer only once last_exception_type = self.db.repr_tmpvar() - self.codewriter.load(last_exception_type, lltype_of_exception_type, '%last_exception_type') + 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, @@ -394,9 +394,9 @@ tmpvar1 = self.db.repr_tmpvar() tmpvar2 = self.db.repr_tmpvar() tmpvar3 = self.db.repr_tmpvar() - self.codewriter.indent('%(tmpvar1)s = getelementptr %(type_)s* null, int 1' % locals()) + self.codewriter.append('%(tmpvar1)s = getelementptr %(type_)s* null, int 1' % locals()) self.codewriter.cast(tmpvar2, type_+'*', tmpvar1, 'uint') - self.codewriter.call(tmpvar3, 'sbyte*', '%malloc_exception', [tmpvar2], ['uint']) + self.codewriter.call(tmpvar3, 'sbyte*', 'malloc_exception', [tmpvar2], ['uint']) self.codewriter.cast(targetvar, 'sbyte*', tmpvar3, type_+'*') def malloc(self, op): Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Fri Oct 7 17:32:10 2005 @@ -1,8 +1,8 @@ import py -from pypy.translator.llvm.log import log -from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode -from pypy.translator.llvm import varsize +from pypy.translator.js.node import LLVMNode, ConstantLLVMNode +from pypy.translator.js import varsize from pypy.rpython import lltype +from pypy.translator.js.log import log log = log.structnode From ericvrp at codespeak.net Fri Oct 7 20:31:50 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 7 Oct 2005 20:31:50 +0200 (CEST) Subject: [pypy-svn] r18269 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051007183150.91D3927B54@code1.codespeak.net> Author: ericvrp Date: Fri Oct 7 20:31:48 2005 New Revision: 18269 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/structnode.py pypy/dist/pypy/translator/js/test/runtest.py pypy/dist/pypy/translator/js/test/test_runtest.py pypy/dist/pypy/translator/js/varsize.py Log: All but one of the trivial tests are passing now. Need to have a good look at the casts for the last one. Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Fri Oct 7 20:31:48 2005 @@ -27,12 +27,10 @@ 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()) + self.ref = self.make_ref('arraytype_', name) + self.constructor_ref = self.make_ref('new_array_', name) + #self.constructor_decl = "%s * %s(%s %%len)" % \ + self.constructor_decl = "%s(len)" % self.constructor_ref def __str__(self): return "" % self.ref @@ -66,7 +64,7 @@ assert isinstance(array, lltype.Array) self.db = db self.array = array - self.ref = "%arraytype.Void" + self.ref = "arraytype_Void" def writedatatypedecl(self, codewriter): td = "%s = type { %s }" % (self.ref, self.db.get_machine_word()) Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Fri Oct 7 20:31:48 2005 @@ -72,7 +72,8 @@ self.llvm("switch %s %s, label %s [%s ]" % (intty, cond, defaultdest, labels)) - def openfunc(self, funcnode, blocks): + def openfunc(self, decl, funcnode, blocks): + self.decl = decl self.funcnode = funcnode self.blocks = blocks usedvars = {} #XXX could probably be limited to inputvars @@ -81,8 +82,9 @@ targetvar = self.js.db.repr_arg(op.result) usedvars[targetvar] = True self.newline() - self.append("function %s {" % self.funcnode.getdecl(), 0) - self.append("var %s" % ' = 0, '.join(usedvars.keys()), 1) + self.append("function %s {" % self.decl, 0) + if usedvars: + self.append("var %s" % ' = 0, '.join(usedvars.keys()), 1) self.append("var block = 0", 1) self.append("while (block != undefined) {", 1) self.append("switch (block) {", 2) @@ -90,7 +92,7 @@ def closefunc(self): self.append("} // end of switch (block)", 2) self.append("} // end of while (block != undefined)", 1) - self.append("} // end of function %s" % self.funcnode.getdecl(), 0) + self.append("} // end of function %s" % self.decl, 0) def ret(self, type_, ref): if type_ == 'void': @@ -153,8 +155,7 @@ self.llvm(s) def getelementptr(self, targetvar, type, typevar, *indices): - word = self.word - res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, %(word)s 0, " % locals() + res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, word 0, " % locals() res += ", ".join(["%s %s" % (t, i) for t, i in indices]) self.llvm(res) @@ -166,8 +167,7 @@ "%(valuetype)s* %(ptr)s" % locals()) def debugcomment(self, tempname, len, tmpname): - word = self.word res = "%s = call ccc %(word)s (sbyte*, ...)* printf(" % locals() - res += "sbyte* getelementptr ([%s x sbyte]* %s, %(word)s 0, %(word)s 0) )" % locals() + res += "sbyte* getelementptr ([%s x sbyte]* %s, word 0, word 0) )" % locals() res = res % (tmpname, len, tmpname) self.llvm(res) Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Fri Oct 7 20:31:48 2005 @@ -84,7 +84,7 @@ self.blockindex= {} for i, block in enumerate(blocks): self.blockindex[block] = i - codewriter.openfunc(self, blocks) + codewriter.openfunc(self.getdecl(), self, blocks) for block in blocks: codewriter.openblock(self.blockindex[block]) for name in 'startblock returnblock exceptblock'.split(): Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Fri Oct 7 20:31:48 2005 @@ -138,15 +138,17 @@ # codewriter.comment("External Function Implementation", 0) # codewriter.append(llexterns_functions) - codewriter.newline() - codewriter.comment("Wrapper code for the Javascript CLI", 0) - codewriter.newline() - graph = self.db.obj2node[entry_point].graph - startblock = graph.startblock - args = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)]) - wrappercode = 'print(pypy_%s(%s))' % (graph.name, args) - codewriter.append(wrappercode, 0) + graph = self.db.obj2node[entry_point].graph + startblock = graph.startblock + args = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)]) + self.wrappertemplate = "load('%s'); print(pypy_%s(%%s))" % (self.filename, graph.name) + + #codewriter.newline() + #codewriter.comment("Wrapper code for the Javascript CLI", 0) + #codewriter.newline() + #codewriter.append(self.wrappercode, 0) codewriter.newline() codewriter.comment("EOF", 0) + log('Written:', self.filename) return self.filename Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Fri Oct 7 20:31:48 2005 @@ -13,7 +13,7 @@ assert isinstance(struct, lltype.Struct) self.db = db self.struct = struct - prefix = '%structtype.' + prefix = 'structtype_' name = self.struct._name self.ref = self.make_ref(prefix, name) self.name = self.ref[len(prefix):] Modified: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/runtest.py (original) +++ pypy/dist/pypy/translator/js/test/runtest.py Fri Oct 7 20:31:48 2005 @@ -28,10 +28,15 @@ self.js.write_source() def __call__(self, *kwds): - #note: lowercase string for (py)False->(js)false, etc. - args = ' '.join([str(kw).lower() for kw in kwds]) - cmd = 'js %s %s' % (self.js.filename, args) + args = ', '.join([str(kw).lower() for kw in kwds]) #lowerstr for (py)False->(js)false, etc. + wrappercode = self.js.wrappertemplate % args + cmd = 'echo "%s" | js' % wrappercode log(cmd) - s = os.popen(cmd).read() - res = eval(s) + s = os.popen(cmd).read().strip() + if s == 'false': + res = False + elif s == 'true': + res = True + else: + res = eval(s) return res Modified: pypy/dist/pypy/translator/js/test/test_runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_runtest.py (original) +++ pypy/dist/pypy/translator/js/test/test_runtest.py Fri Oct 7 20:31:48 2005 @@ -5,12 +5,12 @@ def test_bool_return(): def bool_return_False(): return False - def bool_return_Trur(): + def bool_return_True(): return True - f_false = compile_function(bool_return_false, []) - f_true = compile_function(bool_return_true , []) - assert f_false() == bool_return_false() - assert f_true() == bool_return_true() + f_false = compile_function(bool_return_False, []) + assert f_false() == bool_return_False() + f_true = compile_function(bool_return_True , []) + assert f_true() == bool_return_True() def test_int_return(): def int_return(): Modified: pypy/dist/pypy/translator/js/varsize.py ============================================================================== --- pypy/dist/pypy/translator/js/varsize.py (original) +++ pypy/dist/pypy/translator/js/varsize.py Fri Oct 7 20:31:48 2005 @@ -3,26 +3,24 @@ def write_constructor(db, codewriter, ref, constructor_decl, ARRAY, indices_to_array=()): + codewriter.comment('TODO: ' + constructor_decl) + return + #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) - word = lentype = db.get_machine_word() - uword = db.get_machine_uword() - - codewriter.openfunc(constructor_decl) + codewriter.openfunc(constructor_decl, None, []) # Need room for NUL terminator if ARRAY is STR.chars: - codewriter.binaryop("add", "%actuallen", lentype, "%len", 1) + codewriter.binaryop("add", "%actuallen", 'word', "%len", 1) else: - codewriter.cast("%actuallen", lentype, "%len", lentype) + codewriter.cast("%actuallen", 'word', "%len", 'word') - elemindices = list(indices_to_array) + [("uint", 1), (lentype, "%actuallen")] + elemindices = list(indices_to_array) + [("uint", 1), ('word', "%actuallen")] codewriter.getelementptr("%size", ref + "*", "null", *elemindices) - codewriter.cast("%usize", elemtype + "*", "%size", uword) + codewriter.cast("%usize", "word*", "%size", 'uword') codewriter.malloc("%ptr", "sbyte", "%usize", atomic=ARRAY._is_atomic()) codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") @@ -31,8 +29,7 @@ codewriter.getelementptr("%arraylength", ref + "*", "%result", *indices_to_arraylength) - codewriter.store(lentype, "%len", "%arraylength") + codewriter.store('word', "%len", "%arraylength") codewriter.ret(ref + "*", "%result") codewriter.closefunc() - From ericvrp at codespeak.net Fri Oct 7 20:59:54 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 7 Oct 2005 20:59:54 +0200 (CEST) Subject: [pypy-svn] r18270 - pypy/dist/pypy/translator/js Message-ID: <20051007185954.AAF4827B54@code1.codespeak.net> Author: ericvrp Date: Fri Oct 7 20:59:54 2005 New Revision: 18270 Modified: pypy/dist/pypy/translator/js/codewriter.py Log: Fixed another cast, last trivial test also passes. Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Fri Oct 7 20:59:54 2005 @@ -84,7 +84,7 @@ self.newline() self.append("function %s {" % self.decl, 0) if usedvars: - self.append("var %s" % ' = 0, '.join(usedvars.keys()), 1) + self.append("var %s" % ', '.join(usedvars.keys()), 1) self.append("var block = 0", 1) self.append("while (block != undefined) {", 1) self.append("switch (block) {", 2) @@ -142,7 +142,7 @@ if targettype == fromtype: self.append("%(targetvar)s = %(fromvar)s%(convfunc)s" % locals()) elif targettype in ('int','uint',): - self.append("%(targetvar)s = 0 + %(fromvar)s" % locals()) + self.append("%(targetvar)s = Math.floor(%(fromvar)s)" % locals()) elif targettype in ('double',): self.append("%(targetvar)s = 0.0 + %(fromvar)s" % locals()) elif targettype in ('bool',): From ericvrp at codespeak.net Fri Oct 7 21:44:34 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 7 Oct 2005 21:44:34 +0200 (CEST) Subject: [pypy-svn] r18272 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051007194434.4165527B62@code1.codespeak.net> Author: ericvrp Date: Fri Oct 7 21:44:33 2005 New Revision: 18272 Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/test/runtest.py Log: * optimize phi nodes * support javascript 'undefined' returntype * various cleanup Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Fri Oct 7 21:44:33 2005 @@ -102,24 +102,40 @@ def phi(self, targetvar, type_, refs, blocknames): assert refs and len(refs) == len(blocknames), "phi node requires blocks" - mergelist = ", ".join( - ["[%s, %s]" % item - for item in zip(refs, blocknames)]) - s = "%s = phi %s %s" % (targetvar, type_, mergelist) - self.llvm(s) - self.append('switch (prevblock) {') - for i, blockname in enumerate(blocknames): - self.append('case %d: %s = %s; break' % (blockname, targetvar, refs[i]), 5) - self.append('} // end of switch (prevblock)') + #mergelist = ", ".join( + # ["[%s, %s]" % item + # for item in zip(refs, blocknames)]) + #s = "%s = phi %s %s" % (targetvar, type_, mergelist) + #self.llvm(s) + all_refs_identical = True + for ref in refs: + if ref != refs[0]: + all_refs_identical = False + break + if all_refs_identical: + if targetvar != refs[0]: + self.append('%s = %s' % (targetvar, refs[0])) + else: + if len(blocknames) == 1: + self.append('%s = %s' % (targetvar, refs[i])) + else: + n = 0 + for i, blockname in enumerate(blocknames): + if targetvar != refs[i]: + if n > 0: + s = 'else ' + else: + s = '' + self.append('%sif (prevblock == %d) %s = %s' % (s, blockname, targetvar, refs[i])) + n += 1 def binaryop(self, name, targetvar, type_, ref1, ref2): - self.llvm("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) conv = { 'mul':'*', 'add':'+', 'sub':'-', 'div':'/' } if name in conv: c = conv[name] self.append("%(targetvar)s = %(ref1)s %(c)s %(ref2)s" % locals()) else: - self.append("TODO: binaryop") + self.llvm("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) def shiftop(self, name, targetvar, type_, ref1, ref2): self.llvm("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) @@ -137,8 +153,6 @@ def cast(self, targetvar, fromtype, fromvar, targettype): if fromtype == 'void' and targettype == 'void': return - self.llvm("%(targetvar)s = cast %(fromtype)s " - "%(fromvar)s to %(targettype)s" % locals()) if targettype == fromtype: self.append("%(targetvar)s = %(fromvar)s%(convfunc)s" % locals()) elif targettype in ('int','uint',): @@ -148,7 +162,7 @@ elif targettype in ('bool',): self.append("%(targetvar)s = %(fromvar)s == 0" % locals()) else: - self.append("// TODO %(targetvar)s = %(fromvar)s...()" % locals()) + self.llvm("%(targetvar)s = cast %(fromtype)s %(fromvar)s to %(targettype)s" % locals()) def malloc(self, targetvar, type_, size=1, atomic=False): for s in self.js.gcpolicy.malloc(targetvar, type_, size, atomic, 'word', 'uword').split('\n'): Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Fri Oct 7 21:44:33 2005 @@ -131,7 +131,11 @@ last_val = res_val targetvar = self.db.repr_arg(op.result) self.codewriter.cast(targetvar, mult_type, res_val, mult_type) - + + def _skipped(self, op): + self.codewriter.comment('Skipping operation %s()' % op.opname) + keepalive = _skipped + def int_abs(self, op): functionref = '%' + op.opname ExternalFuncNode.used_external_functions[functionref] = True @@ -442,7 +446,7 @@ ("uint", index)) self.codewriter.load(targetvar, targettype, tmpvar) else: - self.codewriter.comment("***Skipping operation getfield()***") + self._skipped(op) def getsubstruct(self, op): struct, structtype = self.db.repr_argwithtype(op.args[0]) @@ -465,7 +469,7 @@ ("uint", index)) self.codewriter.store(valuetype, valuevar, tmpvar) else: - self.codewriter.comment("***Skipping operation setfield()***") + self._skipped(op) def getarrayitem(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) @@ -479,7 +483,7 @@ ("uint", 1), (indextype, index)) self.codewriter.load(targetvar, targettype, tmpvar) else: - self.codewriter.comment("***Skipping operation getarrayitem()***") + self._skipped(op) def getarraysubstruct(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) @@ -503,7 +507,7 @@ ("uint", 1), (indextype, index)) self.codewriter.store(valuetype, valuevar, tmpvar) else: - self.codewriter.comment("***Skipping operation setarrayitem()***") + self._skipped(op) def getarraysize(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) Modified: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/runtest.py (original) +++ pypy/dist/pypy/translator/js/test/runtest.py Fri Oct 7 21:44:33 2005 @@ -30,13 +30,15 @@ def __call__(self, *kwds): args = ', '.join([str(kw).lower() for kw in kwds]) #lowerstr for (py)False->(js)false, etc. wrappercode = self.js.wrappertemplate % args - cmd = 'echo "%s" | js' % wrappercode + cmd = 'echo "%s" | js 2>&1' % wrappercode log(cmd) s = os.popen(cmd).read().strip() if s == 'false': res = False elif s == 'true': res = True + elif s == 'undefined': + res = None else: res = eval(s) return res From ericvrp at codespeak.net Fri Oct 7 22:08:43 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 7 Oct 2005 22:08:43 +0200 (CEST) Subject: [pypy-svn] r18273 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051007200843.B239127B56@code1.codespeak.net> Author: ericvrp Date: Fri Oct 7 22:08:42 2005 New Revision: 18273 Added: pypy/dist/pypy/translator/js/test/test_class.py (contents, props changed) Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/opwriter.py Log: * Added comparison and condition branches (exitswitch) * Added testfile which needs PBC's to pass more tests Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Fri Oct 7 22:08:42 2005 @@ -62,8 +62,9 @@ #self.llvm("br label %s" %(blockname,)) def br(self, cond, blockname_false, blockname_true): - self.llvm("br bool %s, label %s, label %s" - % (cond, blockname_true, blockname_false)) + self.append('prevblock = block') + self.append('block = %s ? %d : %d' % (cond, blockname_true, blockname_false)) + #self.llvm("br bool %s, label %s, label %s" % (cond, blockname_true, blockname_false)) def switch(self, intty, cond, defaultdest, value_label): labels = '' @@ -130,10 +131,10 @@ n += 1 def binaryop(self, name, targetvar, type_, ref1, ref2): - conv = { 'mul':'*', 'add':'+', 'sub':'-', 'div':'/' } - if name in conv: - c = conv[name] - self.append("%(targetvar)s = %(ref1)s %(c)s %(ref2)s" % locals()) + arithmetic = '*/+-' + comparison = ('<', '<=', '==', '!=', '>=', '>') + if name in arithmetic or name in comparison: + self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) else: self.llvm("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Fri Oct 7 22:08:42 2005 @@ -7,57 +7,57 @@ log = log.opwriter class OpWriter(object): - binary_operations = {'int_mul': 'mul', - 'int_add': 'add', - 'int_sub': 'sub', - 'int_floordiv': 'div', + binary_operations = {'int_mul': '*', + 'int_add': '+', + 'int_sub': '-', + 'int_floordiv': '/', 'int_mod': 'rem', 'int_and': 'and', 'int_or': 'or', 'int_xor': 'xor', - 'int_lt': 'setlt', - 'int_le': 'setle', - 'int_eq': 'seteq', - 'int_ne': 'setne', - 'int_ge': 'setge', - 'int_gt': 'setgt', - - 'uint_mul': 'mul', - 'uint_add': 'add', - 'uint_sub': 'sub', - 'uint_floordiv': 'div', + 'int_lt': '<', + 'int_le': '<=', + 'int_eq': '==', + 'int_ne': '!=', + 'int_ge': '>=', + 'int_gt': '>', + + 'uint_mul': '*', + 'uint_add': '+', + 'uint_sub': '-', + 'uint_floordiv': '/', 'uint_mod': 'rem', 'uint_and': 'and', 'uint_or': 'or', 'uint_xor': 'xor', - 'uint_lt': 'setlt', - 'uint_le': 'setle', - 'uint_eq': 'seteq', - 'uint_ne': 'setne', - 'uint_ge': 'setge', - 'uint_gt': 'setgt', - - 'unichar_lt': 'setlt', - 'unichar_le': 'setle', - 'unichar_eq': 'seteq', - 'unichar_ne': 'setne', - 'unichar_ge': 'setge', - 'unichar_gt': 'setgt', - - 'float_mul': 'mul', - 'float_add': 'add', - 'float_sub': 'sub', - 'float_truediv': 'div', + 'uint_lt': '<', + 'uint_le': '<=', + 'uint_eq': '==', + 'uint_ne': '!=', + 'uint_ge': '>=', + 'uint_gt': '>', + + 'unichar_lt': '<', + 'unichar_le': '<=', + 'unichar_eq': '==', + 'unichar_ne': '!=', + 'unichar_ge': '>=', + 'unichar_gt': '>', + + 'float_mul': '*', + 'float_add': '+', + 'float_sub': '-', + 'float_truediv': '/', 'float_mod': 'rem', - 'float_lt': 'setlt', - 'float_le': 'setle', - 'float_eq': 'seteq', - 'float_ne': 'setne', - 'float_ge': 'setge', - 'float_gt': 'setgt', + 'float_lt': '<', + 'float_le': '<=', + 'float_eq': '==', + 'float_ne': '!=', + 'float_ge': '>=', + 'float_gt': '>', - 'ptr_eq': 'seteq', - 'ptr_ne': 'setne', + 'ptr_eq': '==', + 'ptr_ne': '!=', } shift_operations = {'int_lshift': 'shl', @@ -68,12 +68,12 @@ } - char_operations = {'char_lt': 'setlt', - 'char_le': 'setle', - 'char_eq': 'seteq', - 'char_ne': 'setne', - 'char_ge': 'setge', - 'char_gt': 'setgt'} + char_operations = {'char_lt': '<', + 'char_le': '<=', + 'char_eq': '==', + 'char_ne': '!=', + 'char_ge': '>=', + 'char_gt': '>'} def __init__(self, db, codewriter, node, block): self.db = db @@ -133,7 +133,8 @@ self.codewriter.cast(targetvar, mult_type, res_val, mult_type) def _skipped(self, op): - self.codewriter.comment('Skipping operation %s()' % op.opname) + #self.codewriter.comment('Skipping operation %s()' % op.opname) + pass keepalive = _skipped def int_abs(self, op): @@ -247,7 +248,7 @@ same_as = cast_primitive def int_is_true(self, op): - self.codewriter.binaryop("setne", + self.codewriter.binaryop("!=", self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), @@ -255,21 +256,21 @@ uint_is_true = int_is_true def float_is_true(self, op): - self.codewriter.binaryop("setne", + self.codewriter.binaryop("!=", self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "0.0") def ptr_nonzero(self, op): - self.codewriter.binaryop("setne", + self.codewriter.binaryop("!=", self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "null") def ptr_iszero(self, op): - self.codewriter.binaryop("seteq", + self.codewriter.binaryop("==", self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), Added: pypy/dist/pypy/translator/js/test/test_class.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/js/test/test_class.py Fri Oct 7 22:08:42 2005 @@ -0,0 +1,78 @@ +from __future__ import division +import py + +from pypy.translator.js.test.runtest import compile_function +from pypy.translator.llvm.test import llvmsnippet + +class TestClass(object): + def test_classsimple(self): + f = compile_function(llvmsnippet.class_simple, []) + assert f() == 14 + + def test_classsimple1(self): + f = compile_function(llvmsnippet.class_simple1, [int]) + assert f(2) == 10 + + def test_id_int(self): + f = compile_function(llvmsnippet.id_int, [int]) + for i in range(1, 20): + assert f(i) == i + + def test_classsimple2(self): + f = compile_function(llvmsnippet.class_simple2, [int]) + assert f(2) == 10 + + def test_inherit1(self): + f = compile_function(llvmsnippet.class_inherit1, []) + assert f() == 11 + + def test_inherit2(self): + f = compile_function(llvmsnippet.class_inherit2, []) + assert f() == 1 + + def test_method_of_base_class(self): + f = compile_function(llvmsnippet.method_of_base_class, []) + assert f() == 14 + + def test_attribute_from_base_class(self): + f = compile_function(llvmsnippet.attribute_from_base_class, []) + assert f() == 4 + + def test_direct_call_of_virtual_method(self): + f = compile_function(llvmsnippet.direct_call_of_virtual_method, []) + assert f() == 14 + + def test_flow_type(self): + f = compile_function(llvmsnippet.flow_type, []) + assert f() == 16 + + def test_merge_class(self): + f = compile_function(llvmsnippet.merge_classes, [bool]) + assert f(True) == 1 + assert f(False) == 2 + + def test_attribute_instance(self): + f = compile_function(llvmsnippet.attribute_instance, [bool]) + assert f(True) == 1 + assert f(False) == 2 + + def test_global_instance(self): + f = compile_function(llvmsnippet.global_instance, [int]) + assert f(-1) == llvmsnippet.global_instance(-1) + for i in range(20): + x = f(i) + y = llvmsnippet.global_instance(i) + assert x == y + + def test_getset(self): + f = compile_function(llvmsnippet.testgetset, [int]) + assert f(15) == 25 + + def test_call_degrading_func(self): + f = compile_function(llvmsnippet.call_degrading_func, [bool]) + assert f(True) == llvmsnippet.call_degrading_func(True) + assert f(False) == llvmsnippet.call_degrading_func(False) + + def test_circular_classdef(self): + f = compile_function(llvmsnippet.circular_classdef, []) + assert f() == 10 From tismer at codespeak.net Sat Oct 8 00:44:14 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 8 Oct 2005 00:44:14 +0200 (CEST) Subject: [pypy-svn] r18275 - pypy/dist/pypy/translator/goal Message-ID: <20051007224414.74DED27B56@code1.codespeak.net> Author: tismer Date: Sat Oct 8 00:44:13 2005 New Revision: 18275 Modified: pypy/dist/pypy/translator/goal/bench-windows.py Log: a new benchmark result, after gc_pypy.dll is in place for Windows. This is remarkably good! We are around 11.5, very nice result. Probably also a result of the new inlining criteria. Modified: pypy/dist/pypy/translator/goal/bench-windows.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-windows.py (original) +++ pypy/dist/pypy/translator/goal/bench-windows.py Sat Oct 8 00:44:13 2005 @@ -10,22 +10,27 @@ current_result = """ executable richards pystone size (MB) -pypy-c-17439-hi 37413 47.8x 678.4 60.5x 5.65 -pypy-c-17600-lo 26352 33.7x 906.2 45.3x 6.43 -pypy-c-17634-lo 20108 25.7x 1023.5 40.1x 6.42 -pypy-c-17649-lo 22612 28.9x 1042.0 39.4x 6.41 -pypy-c-17674-lo 19248 24.6x 1358.8 30.2x 6.40 -pypy-c-17674-hi 12402 15.9x 1941.4 21.1x 7.37 -pypy-c-17439-lo 29638 37.9x 971.4 42.3x 6.49 -pypy-c-17707-hi 14095 18.0x 2092.7 19.6x 7.37 -pypy-c-17707-lo 19102 24.4x 1354.7 30.3x 6.40 +pypy-c-17439 37413 47.7x 678.4 60.7x 5.65 +pypy-c-17600-lo 26352 33.6x 906.2 45.4x 6.43 +pypy-c-17634-lo 20108 25.7x 1023.5 40.2x 6.42 +pypy-c-17649-lo 22612 28.9x 1042.0 39.5x 6.41 +pypy-c-17674-lo 19248 24.6x 1358.8 30.3x 6.40 +pypy-c-17674 12402 15.8x 1941.4 21.2x 7.37 +pypy-c-17439-lo 29638 37.8x 971.4 42.4x 6.49 +pypy-c-17707 14095 18.0x 2092.7 19.7x 7.37 +pypy-c-17707-lo 19102 24.4x 1354.7 30.4x 6.40 pypy-c-17707-lo-range 18786 24.0x 2800.8 14.7x 6.40 -pypy-c-17707-hi-range 13980 17.9x 2899.9 14.2x 7.38 -pypy-c-17743-hi 13944 17.8x 2800.3 14.7x 7.30 -pypy-c-17761-hi-samuele 13243 16.9x 2983.3 13.8x 7.69 -pypy-c-17794-ref-crash 41088 52.5x 1084.5 37.9x 14.62 -pypy-c-17950-hi 12888 16.5x 3203.0 12.8x 5.49 -python 2.4.1 782 1.0x 41058.3 1.0x 0.96 +pypy-c-17707-range 13980 17.8x 2899.9 14.2x 7.38 +pypy-c-17743 13944 17.8x 2800.3 14.7x 7.30 +pypy-c-17761-samuele 13243 16.9x 2983.3 13.8x 7.69 +pypy-c-17794-ref-crash 41088 52.4x 1084.5 37.9x 14.62 +pypy-c-17950 12888 16.4x 3203.0 12.8x 5.49 +pypy-c-18236 9263 11.8x 3702.8 11.1x 5.12 +python 2.4.1 783 1.0x 41150.3 1.0x 0.96 + +Defaults are: --gc=boehm +'lo' indicates --lowmem +STarting with rev. 18236, gc_pypy.dll is used """ import os, sys, pickle, md5 From tismer at codespeak.net Sat Oct 8 00:47:16 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 8 Oct 2005 00:47:16 +0200 (CEST) Subject: [pypy-svn] r18276 - in pypy/dist/pypy/translator: c tool Message-ID: <20051007224716.42C3727B56@code1.codespeak.net> Author: tismer Date: Sat Oct 8 00:47:14 2005 New Revision: 18276 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/tool/cbuild.py Log: initial preparations for the multi-source approach. Currently this is trivial, just allowing for more than one file at all. Disabled for now. The next needed step is to modify all the include files. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sat Oct 8 00:47:14 2005 @@ -43,15 +43,16 @@ if not self.standalone: from pypy.translator.c.symboltable import SymbolTable self.symboltable = SymbolTable() - cfile = gen_source(db, modulename, targetdir, - defines = defines, - exports = {translator.entrypoint.func_name: pf}, - symboltable = self.symboltable) + cfile, extra = gen_source(db, modulename, targetdir, + defines = defines, + exports = {translator.entrypoint.func_name: pf}, + symboltable = self.symboltable) else: - cfile = gen_source_standalone(db, modulename, targetdir, - entrypointname = pfname, - defines = defines) + cfile, extra = gen_source_standalone(db, modulename, targetdir, + entrypointname = pfname, + defines = defines) self.c_source_filename = py.path.local(cfile) + self.extrafiles = extra return cfile @@ -65,7 +66,7 @@ def compile(self): assert self.c_source_filename assert not self._compiled - compile_c_module(self.c_source_filename, + compile_c_module([self.c_source_filename] + self.extrafiles, self.c_source_filename.purebasename, include_dirs = [autopath.this_dir], libraries=self.libraries) @@ -104,8 +105,7 @@ python_inc = sysconfig.get_python_inc() self.executable_name = build_executable([self.c_source_filename], include_dirs = [autopath.this_dir, - python_inc, - autopath.this_dir+'/gc6.5/include',], + python_inc], libraries=self.libraries) self._compiled = True return self.executable_name @@ -124,6 +124,122 @@ # ____________________________________________________________ +class SourceGenerator: + one_source_file = True + + def __init__(self, database, preimplementationlines=[]): + self.database = database + self.preimpl = preimplementationlines + self.extrafiles = [] + self.path = None + + def set_strategy(self, path): + #self.one_source_file = False + # disabled for now, until all the includes are updated! + self.path = path + + def makefile(self, name): + filepath = self.path.join(name) + if name.endswith('.c'): + self.extrafiles.append(filepath) + return filepath.open('w') + + def getextrafiles(self): + return self.extrafiles + + def splitglobalcontainers(self): + return [('theimplementations.c', self.database.globalcontainers())] + + def gen_readable_parts_of_source(self, f): + if self.one_source_file: + return gen_readable_parts_of_main_c_file(f, self.database, + self.preimpl) + # + # All declarations + # + database= self.database + structdeflist = database.getstructdeflist() + name = 'structdef.h' + fi = self.makefile(name) + print >> f, '#include "%s"' % name + print >> fi, '/***********************************************************/' + print >> fi, '/*** Structure definitions ***/' + print >> fi + for node in structdeflist: + print >> fi, 'struct %s;' % node.name + print >> fi + for node in structdeflist: + for line in node.definition(phase=1): + print >> fi, line + print >> fi + print >> fi, '/***********************************************************/' + fi.close() + name = 'forwarddecl.h' + fi = self.makefile(name) + print >> f, '#include "%s"' % name + print >> fi, '/***********************************************************/' + print >> fi, '/*** Forward declarations ***/' + print >> fi + for node in database.globalcontainers(): + for line in node.forward_declaration(): + print >> fi, line + print >> fi + print >> fi, '/***********************************************************/' + fi.close() + + # + # Implementation of functions and global structures and arrays + # + print >> f + print >> f, '/***********************************************************/' + print >> f, '/*** Implementations ***/' + print >> f + for line in self.preimpl: + print >> f, line + print >> f, '#include "src/g_include.h"' + print >> f + name = 'structimpl.c' + print >> f, '/* %s */' % name + fc = self.makefile(name) + print >> fc, '/***********************************************************/' + print >> fc, '/*** Structure Implementations ***/' + print >> fc + print >> fc, '#include "common_header.h"' + print >> fc + for node in structdeflist: + for line in node.definition(phase=2): + print >> fc, line + print >> fc + print >> fc, '/***********************************************************/' + fc.close() + for name, nodes in self.splitglobalcontainers(): + print >> f, '/* %s */' % name + fc = self.makefile(name) + print >> fc, '/***********************************************************/' + print >> fc, '/*** Implementations ***/' + print >> fc + print >> fc, '#include "common_header.h"' + print >> fc, '#include "structdef.h"' + print >> fc, '#include "forwarddecl.h"' + print >> fc + for line in self.preimpl: + print >> fc, line + print >> fc + print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#include "src/g_include.h"' + print >> fc + for node in nodes: + for line in node.implementation(): + print >> fc, line + print >> fc + print >> fc, '/***********************************************************/' + fc.close() + print >> f + +# this function acts as the fallback for small sources for now. +# Maybe we drop this completely if source splitting is the way +# to go. Currently, I'm quite fine with keeping a working fallback. + def gen_readable_parts_of_main_c_file(f, database, preimplementationlines=[]): # # All declarations @@ -198,23 +314,37 @@ targetdir = py.path.local(targetdir) filename = targetdir.join(modulename + '.c') f = filename.open('w') + incfilename = targetdir.join('common_header.h') + fi = incfilename.open('w') # # Header # + print >> f, '#include "common_header.h"' + print >> f defines['PYPY_STANDALONE'] = entrypointname for key, value in defines.items(): - print >> f, '#define %s %s' % (key, value) + print >> fi, '#define %s %s' % (key, value) - print >> f, '#define Py_BUILD_CORE /* for Windows: avoid pulling libs in */' - print >> f, '#include "pyconfig.h"' + print >> fi, '#define Py_BUILD_CORE /* for Windows: avoid pulling libs in */' + print >> fi, '#include "pyconfig.h"' for line in database.gcpolicy.pre_pre_gc_code(): - print >> f, line + print >> fi, line - print >> f, '#include "src/g_prerequisite.h"' + print >> fi, '#include "src/g_prerequisite.h"' for line in database.gcpolicy.pre_gc_code(): - print >> f, line + print >> fi, line + + includes = {} + for node in database.globalcontainers(): + for include in node.includes: + includes[include] = True + includes = includes.keys() + includes.sort() + for include in includes: + print >> fi, '#include <%s>' % (include,) + fi.close() preimplementationlines = list( pre_include_code_lines(database, database.translator.rtyper)) @@ -223,14 +353,16 @@ # 1) All declarations # 2) Implementation of functions and global structures and arrays # - gen_readable_parts_of_main_c_file(f, database, preimplementationlines) + sg = SourceGenerator(database, preimplementationlines) + sg.set_strategy(targetdir) + sg.gen_readable_parts_of_source(f) # 3) start-up code print >> f gen_startupcode(f, database) f.close() - return filename + return filename, sg.getextrafiles() def gen_source(database, modulename, targetdir, defines={}, exports={}, @@ -240,21 +372,25 @@ targetdir = py.path.local(targetdir) filename = targetdir.join(modulename + '.c') f = filename.open('w') + incfilename = targetdir.join('common_header.h') + fi = incfilename.open('w') # # Header # + print >> f, '#include "common_header.h"' + print >> f for key, value in defines.items(): - print >> f, '#define %s %s' % (key, value) + print >> fi, '#define %s %s' % (key, value) - print >> f, '#include "pyconfig.h"' + print >> fi, '#include "pyconfig.h"' for line in database.gcpolicy.pre_pre_gc_code(): - print >> f, line + print >> fi, line - print >> f, '#include "src/g_prerequisite.h"' + print >> fi, '#include "src/g_prerequisite.h"' for line in database.gcpolicy.pre_gc_code(): - print >> f, line + print >> fi, line includes = {} for node in database.globalcontainers(): @@ -263,7 +399,8 @@ includes = includes.keys() includes.sort() for include in includes: - print >> f, '#include <%s>' % (include,) + print >> fi, '#include <%s>' % (include,) + fi.close() if database.translator is None or database.translator.rtyper is None: preimplementationlines = [] @@ -275,7 +412,9 @@ # 1) All declarations # 2) Implementation of functions and global structures and arrays # - gen_readable_parts_of_main_c_file(f, database, preimplementationlines) + sg = SourceGenerator(database, preimplementationlines) + sg.set_strategy(targetdir) + sg.gen_readable_parts_of_source(f) # # Debugging info @@ -377,7 +516,7 @@ f.write(SETUP_PY % locals()) f.close() - return filename + return filename, sg.getextrafiles() SETUP_PY = ''' Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Sat Oct 8 00:47:14 2005 @@ -53,7 +53,7 @@ opt += '/Op' gcv['OPT'] = opt -def compile_c_module(cfile, modname, include_dirs=None, libraries=[]): +def compile_c_module(cfiles, modname, include_dirs=None, libraries=[]): #try: # from distutils.log import set_threshold # set_threshold(10000) @@ -63,7 +63,7 @@ if include_dirs is None: include_dirs = [] - dirpath = cfile.dirpath() + dirpath = cfiles[0].dirpath() lastdir = dirpath.chdir() ensure_correct_math() try: @@ -111,7 +111,7 @@ attrs = { 'name': "testmodule", 'ext_modules': [ - Extension(modname, [str(cfile)], + Extension(modname, [str(cfile) for cfile in cfiles], include_dirs=include_dirs, extra_compile_args=extra_compile_args, libraries=libraries,) @@ -145,7 +145,7 @@ def make_module_from_c(cfile, include_dirs=None): cfile = py.path.local(cfile) modname = cfile.purebasename - compile_c_module(cfile, modname, include_dirs) + compile_c_module([cfile], modname, include_dirs) return import_module_from_directory(cfile.dirpath(), modname) def import_module_from_directory(dir, modname): From pedronis at codespeak.net Sat Oct 8 15:34:03 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 8 Oct 2005 15:34:03 +0200 (CEST) Subject: [pypy-svn] r18282 - pypy/dist/pypy/translator/c/test Message-ID: <20051008133403.A110627B69@code1.codespeak.net> Author: pedronis Date: Sat Oct 8 15:33:58 2005 New Revision: 18282 Modified: pypy/dist/pypy/translator/c/test/test_genc.py Log: inf float in struct test 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 Sat Oct 8 15:33:58 2005 @@ -216,7 +216,23 @@ f1 = compile(fn, []) res = f1() assert res < 0 and res == res / 2 + class Box: + def __init__(self, d): + self.d = d + b1 = Box(x) + b2 = Box(0.0) + + def f(i): + if i: + b = b1 + else: + b = b2 + return b.d + + f1 = compile(f, [int]) + res = f1(1) + assert res > 0 and res == res / 2 def test_x(): class A: From pedronis at codespeak.net Sat Oct 8 15:56:16 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 8 Oct 2005 15:56:16 +0200 (CEST) Subject: [pypy-svn] r18283 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051008135616.4CA8327B6A@code1.codespeak.net> Author: pedronis Date: Sat Oct 8 15:56:13 2005 New Revision: 18283 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/test/test_genc.py Log: store HUGE_VAL at runtime in global constants, it maybe an external Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Sat Oct 8 15:56:13 2005 @@ -24,6 +24,7 @@ self.completedcontainers = 0 self.containerstats = {} self.externalfuncs = {} + self.infs = [] self.namespace = CNameManager() if not standalone: self.pyobjmaker = PyObjMaker(self.namespace, self.get, translator) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sat Oct 8 15:56:13 2005 @@ -294,6 +294,11 @@ for line in database.gcpolicy.gc_startup_code(): print >> f,"\t" + line + # put float infinities in global constants, we should not have so many of them for now to make + # a table+loop preferable + for dest, value in database.infs: + print >> f, "\t%s = %s;" % (dest, value) + firsttime = True for node in database.containerlist: lines = list(node.startupcode()) Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Sat Oct 8 15:56:13 2005 @@ -1,13 +1,13 @@ from __future__ import generators from pypy.rpython.lltype import Struct, Array, FuncType, PyObjectType, typeOf from pypy.rpython.lltype import GcStruct, GcArray, GC_CONTAINER, ContainerType -from pypy.rpython.lltype import parentlink, Ptr, PyObject, Void, OpaqueType +from pypy.rpython.lltype import parentlink, Ptr, PyObject, Void, OpaqueType, Float from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo, Char 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, c_string_constant -from pypy.translator.c.primitive import PrimitiveType +from pypy.translator.c.primitive import PrimitiveType, isinf from pypy.translator.c import extfunc from pypy.rpython.rstr import STR @@ -414,6 +414,9 @@ node = db.getcontainernode(value._obj) expr = 'NULL /*%s*/' % node.name node.where_to_copy_me.append('&%s' % access_expr) + elif typeOf(value) == Float and isinf(value): + db.infs.append(('%s' % access_expr, db.get(value))) + expr = '0.0' else: expr = db.get(value) if typeOf(value) is Void: 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 Sat Oct 8 15:56:13 2005 @@ -221,18 +221,25 @@ def __init__(self, d): self.d = d b1 = Box(x) - b2 = Box(0.0) + b2 = Box(-x) + b3 = Box(1.5) def f(i): - if i: + if i==0: b = b1 - else: + elif i==1: b = b2 + else: + b = b3 return b.d f1 = compile(f, [int]) - res = f1(1) + res = f1(0) assert res > 0 and res == res / 2 + res = f1(1) + assert res < 0 and res == res / 2 + res = f1(3) + assert res == 1.5 def test_x(): class A: From tismer at codespeak.net Sat Oct 8 16:08:35 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 8 Oct 2005 16:08:35 +0200 (CEST) Subject: [pypy-svn] r18284 - pypy/dist/pypy/translator/c Message-ID: <20051008140835.0D7FA27B6A@code1.codespeak.net> Author: tismer Date: Sat Oct 8 16:08:35 2005 New Revision: 18284 Modified: pypy/dist/pypy/translator/c/node.py Log: generating a small comment that tells about patching Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Sat Oct 8 16:08:35 2005 @@ -416,7 +416,8 @@ node.where_to_copy_me.append('&%s' % access_expr) elif typeOf(value) == Float and isinf(value): db.infs.append(('%s' % access_expr, db.get(value))) - expr = '0.0' + expr = '0.0 /* patched later by %sinfinity */' % ( + '-+'[value > 0]) else: expr = db.get(value) if typeOf(value) is Void: From tismer at codespeak.net Sat Oct 8 16:09:59 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 8 Oct 2005 16:09:59 +0200 (CEST) Subject: [pypy-svn] r18285 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051008140959.3AA6827B6A@code1.codespeak.net> Author: tismer Date: Sat Oct 8 16:09:53 2005 New Revision: 18285 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/debuginfo.h pypy/dist/pypy/translator/c/src/exception.h pypy/dist/pypy/translator/c/src/int.h pypy/dist/pypy/translator/c/src/ll_math.h pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/src/ll_strtod.h pypy/dist/pypy/translator/c/src/ll_thread.h pypy/dist/pypy/translator/c/src/ll_time.h pypy/dist/pypy/translator/c/src/main.h pypy/dist/pypy/translator/c/src/module.h pypy/dist/pypy/translator/c/src/rtyper.h pypy/dist/pypy/translator/c/src/support.h pypy/dist/pypy/translator/c/src/thread_nt.h pypy/dist/pypy/translator/c/src/thread_pthread.h pypy/dist/pypy/translator/c/src/trace.h Log: modified all include files to support inclusion into a non-main module. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sat Oct 8 16:09:53 2005 @@ -204,7 +204,10 @@ print >> fc, '/***********************************************************/' print >> fc, '/*** Structure Implementations ***/' print >> fc + print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' + print >> fc, '#include "structdef.h"' + print >> fc, '#include "forwarddecl.h"' print >> fc for node in structdeflist: for line in node.definition(phase=2): @@ -218,6 +221,7 @@ print >> fc, '/***********************************************************/' print >> fc, '/*** Implementations ***/' print >> fc + print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "common_header.h"' print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' @@ -225,7 +229,6 @@ for line in self.preimpl: print >> fc, line print >> fc - print >> fc, '#define PYPY_NOT_MAIN_FILE' print >> fc, '#include "src/g_include.h"' print >> fc for node in nodes: Modified: pypy/dist/pypy/translator/c/src/debuginfo.h ============================================================================== --- pypy/dist/pypy/translator/c/src/debuginfo.h (original) +++ pypy/dist/pypy/translator/c/src/debuginfo.h Sat Oct 8 16:09:53 2005 @@ -11,6 +11,16 @@ { "debuginfo_global", debuginfo_global, METH_VARARGS }, \ { "debuginfo_peek", debuginfo_peek, METH_VARARGS }, +/* prototypes */ + +static PyObject *debuginfo_offset(PyObject *self, PyObject *args); +static PyObject *debuginfo_global(PyObject *self, PyObject *args); +static PyObject *debuginfo_peek(PyObject *self, PyObject *args); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE static PyObject *debuginfo_offset(PyObject *self, PyObject *args) { @@ -40,3 +50,5 @@ return NULL; return PyString_FromStringAndSize((char *)start, size); } + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -30,7 +30,19 @@ (RPYTHON_EXCEPTION_VTABLE) etype) #ifndef PYPY_STANDALONE -static void RPyConvertExceptionFromCPython(void) + + +/* prototypes */ + +void RPyConvertExceptionFromCPython(void); +void _RPyConvertExceptionToCPython(void); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + +void RPyConvertExceptionFromCPython(void) { /* convert the CPython exception to an RPython one */ PyObject *exc_type, *exc_value, *exc_tb; @@ -42,7 +54,7 @@ rpython_exc_type = RPYTHON_TYPE_OF_EXC_INST(rpython_exc_value); } -static void _RPyConvertExceptionToCPython(void) +void _RPyConvertExceptionToCPython(void) { /* XXX 1. uses officially bad fishing */ /* XXX 2. looks for exception classes by name, fragile */ @@ -61,6 +73,8 @@ } } +#endif /* PYPY_NOT_MAIN_FILE */ + #define RPyConvertExceptionToCPython(vanishing) \ _RPyConvertExceptionToCPython(); \ vanishing = rpython_exc_value; \ 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 Sat Oct 8 16:09:53 2005 @@ -171,6 +171,15 @@ #ifndef HAVE_LONG_LONG /* adjusted from intobject.c, Python 2.3.3 */ + +/* prototypes */ + +op_int_mul_ovf(long a, long b, long *longprod); + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + int op_int_mul_ovf(long a, long b, long *longprod) { @@ -203,10 +212,21 @@ return 0; } } + +#endif /* PYPY_NOT_MAIN_FILE */ + #endif /* HAVE_LONG_LONG */ /* XXX we might probe the compiler whether it does what we want */ +/* prototypes */ + +long op_divmod_adj(long x, long y, long *p_rem); + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + long op_divmod_adj(long x, long y, long *p_rem) { long xdivy = x / y; @@ -225,6 +245,9 @@ *p_rem = xmody; return xdivy; } + +#endif /* PYPY_NOT_MAIN_FILE */ + /* no editing below this point */ /* following lines are generated by mkuint.py */ 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 Sat Oct 8 16:09:53 2005 @@ -11,6 +11,47 @@ /* xxx this 2.3 name is later deprecated */ #define LL_MATH_SET_ERANGE_IF_MATH_ERROR Py_SET_ERANGE_IF_OVERFLOW +#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) + + +/* prototypes */ + +int ll_math_is_error(double x); +double LL_math_pow(double x, double y); +RPyFREXP_RESULT* LL_math_frexp(double x); +double LL_math_atan2(double x, double y); +double LL_math_fmod(double x, double y); +double LL_math_ldexp(double x, long y); +double LL_math_hypot(double x, double y); +RPyMODF_RESULT* LL_math_modf(double x); +double LL_math_acos(double x); +double LL_math_asin(double x); +double LL_math_atan(double x); +double LL_math_ceil(double x); +double LL_math_cos(double x); +double LL_math_cosh(double x); +double LL_math_exp(double x); +double LL_math_fabs(double x); +double LL_math_floor(double x); +double LL_math_log(double x); +double LL_math_log10(double x); +double LL_math_sin(double x); +double LL_math_sinh(double x); +double LL_math_sqrt(double x); +double LL_math_tan(double x); +double LL_math_tanh(double x); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + int ll_math_is_error(double x) { if (errno == ERANGE) { if (!x) @@ -22,17 +63,6 @@ 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; @@ -220,3 +250,5 @@ LL_MATH_CHECK_ERROR(r, -1.0); return r; } + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -36,6 +36,28 @@ #endif +/* prototypes */ + +RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st); +RPySTAT_RESULT* LL_os_stat(RPyString * fname); +RPySTAT_RESULT* LL_os_fstat(long fd); +long LL_os_lseek(long fd, long pos, long how); +long LL_os_isatty(long fd); +RPyString *LL_os_strerror(int errnum); +long LL_os_system(RPyString * fname); +void LL_os_unlink(RPyString * fname); +RPyString *LL_os_getcwd(void); +void LL_os_chdir(RPyString * path); +void LL_os_mkdir(RPyString * path, int mode); +void LL_os_rmdir(RPyString * path); +void LL_os_putenv(RPyString * name_eq_value); +void LL_os_unsetenv(RPyString * name); +RPyString* LL_os_environ(int idx); + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + int LL_os_open(RPyString *filename, int flag, int mode) { /* XXX unicode_file_names */ @@ -169,8 +191,7 @@ } } -RPyString *LL_os_getcwd(void) -{ +RPyString *LL_os_getcwd(void) { char buf[PATH_MAX]; char *res; res = getcwd(buf, sizeof buf); @@ -246,3 +267,4 @@ } return rs; } +#endif /* PYPY_NOT_MAIN_FILE */ 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 Oct 8 16:09:53 2005 @@ -1,6 +1,18 @@ #include #include + +/* prototypes */ + +double LL_strtod_parts_to_float(RPyString *sign, RPyString *beforept, + RPyString *afterpt, RPyString *exponent); +RPyString *LL_strtod_formatd(RPyString *fmt, double x); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + double LL_strtod_parts_to_float( RPyString *sign, RPyString *beforept, @@ -107,3 +119,5 @@ return RPyString_FromString(buffer); } + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -10,6 +10,27 @@ * - the macro redefining LL_thread_newlock (produced by genc) is not defined * yet */ + +#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"; + + +/* prototypes */ + +void LL_thread_newlock(struct RPyOpaque_ThreadLock *lock); +int LL_thread_acquirelock(struct RPyOpaque_ThreadLock *lock, int waitflag); +void LL_thread_releaselock(struct RPyOpaque_ThreadLock *lock); +long LL_thread_start(void *func, void *arg); +long LL_thread_get_ident(void); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + void LL_thread_newlock(struct RPyOpaque_ThreadLock *lock) { if (!RPyThreadLockInit(lock)) @@ -51,8 +72,4 @@ 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"; +#endif /* PYPY_NOT_MAIN_FILE */ 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 Oct 8 16:09:53 2005 @@ -7,6 +7,17 @@ #endif +/* prototypes */ + +double LL_time_clock(void); +void LL_time_sleep(double secs); +double LL_time_time(void); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + /****** clock() ******/ #if defined(MS_WINDOWS) && !defined(MS_WIN64) && !defined(__BORLANDC__) @@ -14,6 +25,7 @@ XXX Win64 does not yet, but might when the platform matures. */ #include + double LL_time_clock(void) { static LARGE_INTEGER ctrStart; @@ -149,3 +161,5 @@ { return ll_floattime(); } + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -4,6 +4,15 @@ char *RPython_StartupCode(void); /* forward */ +/* prototypes */ + +int main(int argc, char *argv[]); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + int main(int argc, char *argv[]) { char *errmsg; @@ -35,3 +44,5 @@ fprintf(stderr, "Fatal error during initialization: %s\n", errmsg); return 1; } + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -57,6 +57,11 @@ PyMethodDef ml; } globalfunctiondef_t; + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + static int setup_globalobjects(globalobjectdef_t* def) { PyObject* obj; @@ -134,3 +139,5 @@ Py_DECREF(res); return 0; } + +#endif /* PYPY_NOT_MAIN_FILE */ Modified: pypy/dist/pypy/translator/c/src/rtyper.h ============================================================================== --- pypy/dist/pypy/translator/c/src/rtyper.h (original) +++ pypy/dist/pypy/translator/c/src/rtyper.h Sat Oct 8 16:09:53 2005 @@ -7,6 +7,16 @@ #define RPyString_Size(rps) ((rps)->rs_chars.length) #define RPyString_AsString(rps) ((rps)->rs_chars.items) + +/* prototypes */ + +RPyString *RPyString_FromString(char *buf); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + RPyString *RPyString_FromString(char *buf) { int length = strlen(buf); @@ -14,3 +24,5 @@ memcpy(RPyString_AsString(rps), buf, length); return rps; } + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -19,12 +19,38 @@ #define FAIL_ZER(err, msg) FAIL_EXCEPTION(err, PyExc_ZeroDivisionError, msg) #define CFAIL(err) { RPyConvertExceptionFromCPython(); FAIL(err); } +#define PyString_FromLLCharArrayAndSize(itemsarray, size) \ + PyString_FromStringAndSize(itemsarray->items, size) + +#define PyString_ToLLCharArray(s, itemsarray) \ + memcpy(itemsarray->items, PyString_AS_STRING(s), \ + itemsarray->length) #ifndef PYPY_STANDALONE +/* prototypes */ + +PyObject * gencfunc_descr_get(PyObject *func, PyObject *obj, PyObject *type); +PyObject* PyList_Pack(int n, ...); +PyObject* PyDict_Pack(int n, ...); +PyObject* PyTuple_Pack(int n, ...); +PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index); +PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v); +PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...); +PyObject* decode_arg(PyObject* fname, int position, PyObject* name, + PyObject* vargs, PyObject* vkwds, PyObject* def); +int check_no_more_arg(PyObject* fname, int n, PyObject* vargs); +PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index); +int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + /* we need a subclass of 'builtin_function_or_method' which can be used as methods: builtin function objects that can be bound on instances */ -static PyObject * +PyObject * gencfunc_descr_get(PyObject *func, PyObject *obj, PyObject *type) { if (obj == Py_None) @@ -72,7 +98,7 @@ /*** misc support functions ***/ -static PyObject* PyList_Pack(int n, ...) +PyObject* PyList_Pack(int n, ...) { int i; PyObject *o; @@ -93,7 +119,7 @@ return result; } -static PyObject* PyDict_Pack(int n, ...) +PyObject* PyDict_Pack(int n, ...) { int i; PyObject *key, *val; @@ -118,7 +144,7 @@ } #if PY_VERSION_HEX < 0x02040000 /* 2.4 */ -static PyObject* PyTuple_Pack(int n, ...) +PyObject* PyTuple_Pack(int n, ...) { int i; PyObject *o; @@ -147,7 +173,7 @@ # define PyObject_SetItem1 PyObject_SetItem #else /* for Python 2.2 only */ -static PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index) +PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index) { int start, stop, step; if (!PySlice_Check(index)) { @@ -182,7 +208,8 @@ } return PySequence_GetSlice(obj, start, stop); } -static PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v) + +PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v) { int start, stop, step; if (!PySlice_Check(index)) { @@ -219,7 +246,7 @@ } #endif -static PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...) +PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...) { /* XXX the 'shape' argument is a tuple as specified by XXX pypy.interpreter.argument.fromshape(). This code should @@ -304,7 +331,7 @@ return result; } -static PyObject* decode_arg(PyObject* fname, int position, PyObject* name, +PyObject* decode_arg(PyObject* fname, int position, PyObject* name, PyObject* vargs, PyObject* vkwds, PyObject* def) { PyObject* result; @@ -342,7 +369,7 @@ return NULL; } -static int check_no_more_arg(PyObject* fname, int n, PyObject* vargs) +int check_no_more_arg(PyObject* fname, int n, PyObject* vargs) { int size = PyTuple_Size(vargs); if (size < 0) @@ -359,23 +386,19 @@ /************************************************************/ -static PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index) +PyObject *PyTuple_GetItem_WithIncref(PyObject *tuple, int index) { PyObject *result = PyTuple_GetItem(tuple, index); Py_XINCREF(result); return result; } -static int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o) +int PyTuple_SetItem_WithIncref(PyObject *tuple, int index, PyObject *o) { Py_INCREF(o); return PyTuple_SetItem(tuple, index, o); } -#define PyString_FromLLCharArrayAndSize(itemsarray, size) \ - PyString_FromStringAndSize(itemsarray->items, size) - -#define PyString_ToLLCharArray(s, itemsarray) \ - memcpy(itemsarray->items, PyString_AS_STRING(s), \ - itemsarray->length) #endif /* PYPY_STANDALONE */ + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -26,6 +26,27 @@ HANDLE done; } callobj; +typedef struct RPyOpaque_ThreadLock { + LONG owned ; + DWORD thread_id ; + HANDLE hevent ; +} NRMUTEX, *PNRMUTEX ; + +/* prototypes */ +long RPyThreadStart(void (*func)(void *), void *arg); +BOOL InitializeNonRecursiveMutex(PNRMUTEX mutex); +VOID DeleteNonRecursiveMutex(PNRMUTEX mutex); +DWORD EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait); +BOOL LeaveNonRecursiveMutex(PNRMUTEX mutex); +void RPyOpaqueDealloc_ThreadLock(struct RPyOpaque_ThreadLock *lock); +int RPyThreadAcquireLock(struct RPyOpaque_ThreadLock *lock, int waitflag); +void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE + static int bootstrap(void *call) { @@ -70,12 +91,6 @@ /************************************************************/ -typedef struct RPyOpaque_ThreadLock { - LONG owned ; - DWORD thread_id ; - HANDLE hevent ; -} NRMUTEX, *PNRMUTEX ; - #define RPyOpaque_INITEXPR_ThreadLock { 0, 0, NULL } @@ -205,3 +220,5 @@ if (!LeaveNonRecursiveMutex(lock)) /* XXX complain? */; } + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -39,6 +39,23 @@ #define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; } +/* prototypes */ + +long RPyThreadGetIdent(void); +long RPyThreadStart(void (*func)(void *), void *arg); +int RPyThreadLockInit(struct RPyOpaque_ThreadLock *lock); +void RPyOpaqueDealloc_ThreadLock(struct RPyOpaque_ThreadLock *lock); +int RPyThreadAcquireLock(struct RPyOpaque_ThreadLock *lock, int waitflag); +void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock); +int RPyThreadLockInit(struct RPyOpaque_ThreadLock *lock); +void RPyOpaqueDealloc_ThreadLock(struct RPyOpaque_ThreadLock *lock); +int RPyThreadAcquireLock(struct RPyOpaque_ThreadLock *lock, int waitflag); +void RPyThreadReleaseLock(struct RPyOpaque_ThreadLock *lock); + + +/* implementations */ + +#ifndef PYPY_NOT_MAIN_FILE /* XXX This implementation is considered (to quote Tim Peters) "inherently hosed" because: @@ -288,3 +305,5 @@ /************************************************************/ #endif /* no semaphores */ /************************************************************/ + +#endif /* PYPY_NOT_MAIN_FILE */ 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 Sat Oct 8 16:09:53 2005 @@ -39,6 +39,8 @@ /*** Implementation ***/ +#ifndef PYPY_NOT_MAIN_FILE + #if defined(USE_CALL_TRACE) static int callstack_depth = -1; @@ -307,3 +309,5 @@ } #endif /* defined(USE_CALL_TRACE) */ + +#endif /* PYPY_NOT_MAIN_FILE */ From pedronis at codespeak.net Sat Oct 8 17:00:44 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 8 Oct 2005 17:00:44 +0200 (CEST) Subject: [pypy-svn] r18289 - pypy/dist/pypy/translator/c/src Message-ID: <20051008150044.B596A27B6C@code1.codespeak.net> Author: pedronis Date: Sat Oct 8 17:00:41 2005 New Revision: 18289 Modified: pypy/dist/pypy/translator/c/src/thread_pthread.h Log: missing struct declarations before use in the func prototypes 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 Sat Oct 8 17:00:41 2005 @@ -39,6 +39,38 @@ #define CHECK_STATUS(name) if (status != 0) { perror(name); error = 1; } +/********************* structs ***********/ + +#ifdef USE_SEMAPHORES + +#include + +struct RPyOpaque_ThreadLock { + sem_t sem; + int initialized; +}; + +#define RPyOpaque_INITEXPR_ThreadLock { { /* sem */ }, 0 } + +#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; +}; + +#define RPyOpaque_INITEXPR_ThreadLock { \ + 0, 0, \ + PTHREAD_COND_INITIALIZER, \ + PTHREAD_MUTEX_INITIALIZER \ + } +#endif /* no semaphores */ + /* prototypes */ long RPyThreadGetIdent(void); @@ -126,13 +158,6 @@ #include -struct RPyOpaque_ThreadLock { - sem_t sem; - int initialized; -}; - -#define RPyOpaque_INITEXPR_ThreadLock { { /* sem */ }, 0 } - int RPyThreadLockInit(struct RPyOpaque_ThreadLock *lock) { int status, error = 0; @@ -204,22 +229,6 @@ #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; -}; - -#define RPyOpaque_INITEXPR_ThreadLock { \ - 0, 0, \ - PTHREAD_COND_INITIALIZER, \ - PTHREAD_MUTEX_INITIALIZER \ - } - int RPyThreadLockInit(struct RPyOpaque_ThreadLock *lock) { int status, error = 0; From tismer at codespeak.net Sat Oct 8 18:34:10 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 8 Oct 2005 18:34:10 +0200 (CEST) Subject: [pypy-svn] r18290 - pypy/extradoc/sprintinfo Message-ID: <20051008163410.C118927B64@code1.codespeak.net> Author: tismer Date: Sat Oct 8 18:34:09 2005 New Revision: 18290 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: the all_interior_pointers windows issue is fixed. what remains is the fact that I still crash with x=range(10**7) Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Sat Oct 8 18:34:09 2005 @@ -50,7 +50,7 @@ ----------------- - look into implementing weakrefs -- Boehm: fix the all_interior_pointers=0 vs. Windows issue +- Boehm: fix the x=range(10**7) issue - (improve refcounting) - (passes toward integrating other GCs, rpython/memory) From tismer at codespeak.net Sat Oct 8 20:09:34 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 8 Oct 2005 20:09:34 +0200 (CEST) Subject: [pypy-svn] r18293 - pypy/dist/pypy/translator/c Message-ID: <20051008180934.B789E27B69@code1.codespeak.net> Author: tismer Date: Sat Oct 8 20:09:33 2005 New Revision: 18293 Modified: pypy/dist/pypy/translator/c/genc.py Log: implemented some primitive source splitting. There is still something wrong, the source compiles, but the exe crashes. Investigating... Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sat Oct 8 20:09:33 2005 @@ -3,7 +3,7 @@ from pypy.translator.c.node import PyObjectNode from pypy.translator.c.database import LowLevelDatabase from pypy.translator.c.extfunc import pre_include_code_lines -from pypy.translator.gensupp import uniquemodulename +from pypy.translator.gensupp import uniquemodulename, NameManager 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 @@ -103,10 +103,10 @@ # 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, - python_inc], - libraries=self.libraries) + self.executable_name = build_executable( + [self.c_source_filename] + self.extrafiles, + include_dirs = [autopath.this_dir, python_inc], + libraries=self.libraries) self._compiled = True return self.executable_name @@ -124,6 +124,8 @@ # ____________________________________________________________ +SPLIT_CRITERIA = 2000 + class SourceGenerator: one_source_file = True @@ -132,12 +134,19 @@ self.preimpl = preimplementationlines self.extrafiles = [] self.path = None + self.namespace = NameManager() def set_strategy(self, path): - #self.one_source_file = False - # disabled for now, until all the includes are updated! + self.all_nodes = list(self.database.globalcontainers()) + if len(self.all_nodes) >= SPLIT_CRITERIA: + pass # self.one_source_file = False + # disabled. still a problem: compiles but infinite recursion etc. self.path = path + def uniquecname(self, name): + assert name.endswith('.c') + return self.namespace.uniquename(name[:-2]) + '.c' + def makefile(self, name): filepath = self.path.join(name) if name.endswith('.c'): @@ -148,7 +157,14 @@ return self.extrafiles def splitglobalcontainers(self): - return [('theimplementations.c', self.database.globalcontainers())] + # silly first split, just by node count + # XXX filter constant stuff off and put it elsewhere + nodes = self.all_nodes[:] + nchunks = len(nodes) // SPLIT_CRITERIA + chunksize = (len(nodes) + nchunks - 1) // nchunks + while nodes: + yield self.uniquecname('implement.c'), nodes[:chunksize] + del nodes[:chunksize] def gen_readable_parts_of_source(self, f): if self.one_source_file: @@ -198,7 +214,7 @@ print >> f, line print >> f, '#include "src/g_include.h"' print >> f - name = 'structimpl.c' + name = self.uniquecname('structimpl.c') print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' From cfbolz at codespeak.net Sun Oct 9 16:53:18 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 9 Oct 2005 16:53:18 +0200 (CEST) Subject: [pypy-svn] r18314 - in pypy/dist/pypy/translator/backendopt: . test Message-ID: <20051009145318.935CE27B66@code1.codespeak.net> Author: cfbolz Date: Sun Oct 9 16:53:15 2005 New Revision: 18314 Modified: pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/test/test_propagate.py Log: (cfbolz, arigo): don't generate keepalive for constants and atomic structures. Fix the (admittedly stupid) test in test_propagate. Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Sun Oct 9 16:53:15 2005 @@ -133,6 +133,10 @@ def generate_keepalive(vars): keepalive_ops = [] for v in vars: + if isinstance(v, Constant): + continue + if v.concretetype._is_atomic(): + continue v_keepalive = Variable() v_keepalive.concretetype = Void keepalive_ops.append(SpaceOperation('keepalive', [v], v_keepalive)) Modified: pypy/dist/pypy/translator/backendopt/test/test_propagate.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_propagate.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_propagate.py Sun Oct 9 16:53:15 2005 @@ -82,7 +82,7 @@ graph, t = get_graph(g, [int]) partial_folding(graph, t) constant_folding(graph, t) - assert len(graph.startblock.operations) == 3 + assert len(graph.startblock.operations) == 1 check_graph(graph, [10], g(10), t) def getitem(l, i): #LookupError, KeyError From cfbolz at codespeak.net Mon Oct 10 09:52:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 10 Oct 2005 09:52:17 +0200 (CEST) Subject: [pypy-svn] r18320 - pypy/dist/pypy/translator/goal Message-ID: <20051010075217.D307027B6A@code1.codespeak.net> Author: cfbolz Date: Mon Oct 10 09:52:15 2005 New Revision: 18320 Modified: pypy/dist/pypy/translator/goal/targetrichards.py pypy/dist/pypy/translator/goal/targetrpystone.py Log: fix get_llinterp_args for richards and rpystone Modified: pypy/dist/pypy/translator/goal/targetrichards.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrichards.py (original) +++ pypy/dist/pypy/translator/goal/targetrichards.py Mon Oct 10 09:52:15 2005 @@ -8,7 +8,7 @@ return entry_point, [int] def get_llinterp_args(): - return [] + return [1] # _____ Run translated _____ def run(c_entry_point): Modified: pypy/dist/pypy/translator/goal/targetrpystone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrpystone.py (original) +++ pypy/dist/pypy/translator/goal/targetrpystone.py Mon Oct 10 09:52:15 2005 @@ -10,3 +10,6 @@ (entry_point, target, run) = targetrpystonex.make_target_definition(LOOPS) + +def get_llinterp_args(): + return [1] From ericvrp at codespeak.net Mon Oct 10 09:55:45 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 10 Oct 2005 09:55:45 +0200 (CEST) Subject: [pypy-svn] r18321 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051010075545.2B01627B6A@code1.codespeak.net> Author: ericvrp Date: Mon Oct 10 09:55:41 2005 New Revision: 18321 Added: pypy/dist/pypy/translator/js/test/test_exc_operation.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_exc_operation.py pypy/dist/pypy/translator/js/test/test_exception.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_exception.py pypy/dist/pypy/translator/js/test/test_genllvm.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_genllvm.py pypy/dist/pypy/translator/js/test/test_genllvm1.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_genllvm1.py pypy/dist/pypy/translator/js/test/test_lltype.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_lltype.py pypy/dist/pypy/translator/js/test/test_seq.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_seq.py pypy/dist/pypy/translator/js/test/test_snippet.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_snippet.py pypy/dist/pypy/translator/js/test/test_typed.py - copied, changed from r18226, pypy/dist/pypy/translator/llvm/test/test_typed.py Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/opwriter.py Log: * Added rem,and,xor and or operations * Added more tests [43 passed, 120 failed] Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Mon Oct 10 09:55:41 2005 @@ -131,7 +131,7 @@ n += 1 def binaryop(self, name, targetvar, type_, ref1, ref2): - arithmetic = '*/+-' + arithmetic = '*/+-%^&|' comparison = ('<', '<=', '==', '!=', '>=', '>') if name in arithmetic or name in comparison: self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Mon Oct 10 09:55:41 2005 @@ -11,10 +11,10 @@ 'int_add': '+', 'int_sub': '-', 'int_floordiv': '/', - 'int_mod': 'rem', - 'int_and': 'and', - 'int_or': 'or', - 'int_xor': 'xor', + 'int_mod': '%', + 'int_and': '&', + 'int_or': '|', + 'int_xor': '^', 'int_lt': '<', 'int_le': '<=', 'int_eq': '==', @@ -26,10 +26,10 @@ 'uint_add': '+', 'uint_sub': '-', 'uint_floordiv': '/', - 'uint_mod': 'rem', - 'uint_and': 'and', - 'uint_or': 'or', - 'uint_xor': 'xor', + 'uint_mod': '%', + 'uint_and': '&', + 'uint_or': '|', + 'uint_xor': '^', 'uint_lt': '<', 'uint_le': '<=', 'uint_eq': '==', @@ -48,7 +48,7 @@ 'float_add': '+', 'float_sub': '-', 'float_truediv': '/', - 'float_mod': 'rem', + 'float_mod': '%', 'float_lt': '<', 'float_le': '<=', 'float_eq': '==', @@ -123,7 +123,7 @@ res_val = mult_val for ii in range(operand - 1): res_val = self.db.repr_tmpvar() - self.codewriter.binaryop("mul", + self.codewriter.binaryop('*', res_val, mult_type, last_val, @@ -172,21 +172,21 @@ self._generic_neg(op, "0.0") def bool_not(self, op): - self.codewriter.binaryop("xor", + self.codewriter.binaryop('^', self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "true") def int_invert(self, op): - self.codewriter.binaryop("xor", + self.codewriter.binaryop('^', self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), -1) def uint_invert(self, op): - self.codewriter.binaryop("xor", + self.codewriter.binaryop('^', self.db.repr_arg(op.result), self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), From cfbolz at codespeak.net Mon Oct 10 10:12:21 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 10 Oct 2005 10:12:21 +0200 (CEST) Subject: [pypy-svn] r18323 - pypy/extradoc/sprintinfo Message-ID: <20051010081221.0204D27B5B@code1.codespeak.net> Author: cfbolz Date: Mon Oct 10 10:12:20 2005 New Revision: 18323 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: one more nice task Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Mon Oct 10 10:12:20 2005 @@ -16,6 +16,7 @@ JIT related work ----------------- +- support addresses in the backends - an ll interpreter written in RPython - Saving ll graphs plus a loader written in RPython From tismer at codespeak.net Mon Oct 10 10:24:53 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 10 Oct 2005 10:24:53 +0200 (CEST) Subject: [pypy-svn] r18324 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051010082453.0635627B4D@code1.codespeak.net> Author: tismer Date: Mon Oct 10 10:24:49 2005 New Revision: 18324 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/debuginfo.h pypy/dist/pypy/translator/c/src/exception.h pypy/dist/pypy/translator/c/src/int.h pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/src/thread_nt.h Log: some so-far working source splitting. This is just a start to have small source files at all (makes debugging with Windows possible). Next thing to do is figuring out source info and grouping pieces together. (p.s.: Armin fixed a bug in my include file patches) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Mon Oct 10 10:24:49 2005 @@ -124,7 +124,9 @@ # ____________________________________________________________ -SPLIT_CRITERIA = 2000 +SPLIT_CRITERIA = 170 + +MARKER = '/*/*/' # provide an easy way to split after generating class SourceGenerator: one_source_file = True @@ -137,10 +139,22 @@ self.namespace = NameManager() def set_strategy(self, path): - self.all_nodes = list(self.database.globalcontainers()) - if len(self.all_nodes) >= SPLIT_CRITERIA: - pass # self.one_source_file = False - # disabled. still a problem: compiles but infinite recursion etc. + all_nodes = list(self.database.globalcontainers()) + # split off non-function nodes + # win32 has a problem: compiles but infinite recursion etc. + # trytocicumvent this by placing all non-func nodes into one file. + funcnodes = [] + othernodes = [] + for node in all_nodes: + if node.nodekind == 'func': + funcnodes.append(node) + else: + othernodes.append(node) + #if len(funcnodes) >= SPLIT_CRITERIA: + # always now + self.one_source_file = False + self.funcnodes = funcnodes + self.othernodes = othernodes self.path = path def uniquecname(self, name): @@ -156,11 +170,14 @@ def getextrafiles(self): return self.extrafiles - def splitglobalcontainers(self): + def getothernodes(self): + return self.othernodes[:] + + def splitfuncnodes(self): # silly first split, just by node count # XXX filter constant stuff off and put it elsewhere - nodes = self.all_nodes[:] - nchunks = len(nodes) // SPLIT_CRITERIA + nodes = self.funcnodes[:] + nchunks = len(nodes) // SPLIT_CRITERIA or 1 chunksize = (len(nodes) + nchunks - 1) // nchunks while nodes: yield self.uniquecname('implement.c'), nodes[:chunksize] @@ -225,13 +242,43 @@ print >> fc, '#include "structdef.h"' print >> fc, '#include "forwarddecl.h"' print >> fc + print >> fc, '#include "src/g_include.h"' + print >> fc + print >> fc, MARKER + + def render_nonempty(seq): + lines = list(seq) + if lines: + print >> fc, '\n'.join(lines) + print >> fc, MARKER + return len(lines) + 1 + return 0 + for node in structdeflist: - for line in node.definition(phase=2): - print >> fc, line + render_nonempty(node.definition(phase=2)) + print >> fc, '/***********************************************************/' + fc.close() + + name = self.uniquecname('nonfuncnodes.c') + print >> f, '/* %s */' % name + fc = self.makefile(name) + print >> fc, '/***********************************************************/' + print >> fc, '/*** Non-function Implementations ***/' + print >> fc + print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#include "common_header.h"' + print >> fc, '#include "structdef.h"' + print >> fc, '#include "forwarddecl.h"' + print >> fc + print >> fc, '#include "src/g_include.h"' print >> fc + print >> fc, MARKER + for node in self.getothernodes(): + render_nonempty(node.implementation()) print >> fc, '/***********************************************************/' fc.close() - for name, nodes in self.splitglobalcontainers(): + + for name, nodes in self.splitfuncnodes(): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' @@ -247,10 +294,10 @@ print >> fc print >> fc, '#include "src/g_include.h"' print >> fc + print >> fc, MARKER + linecount = 12 + len(self.preimpl) for node in nodes: - for line in node.implementation(): - print >> fc, line - print >> fc + linecount += render_nonempty(node.implementation()) print >> fc, '/***********************************************************/' fc.close() print >> f Modified: pypy/dist/pypy/translator/c/src/debuginfo.h ============================================================================== --- pypy/dist/pypy/translator/c/src/debuginfo.h (original) +++ pypy/dist/pypy/translator/c/src/debuginfo.h Mon Oct 10 10:24:49 2005 @@ -13,16 +13,16 @@ /* prototypes */ -static PyObject *debuginfo_offset(PyObject *self, PyObject *args); -static PyObject *debuginfo_global(PyObject *self, PyObject *args); -static PyObject *debuginfo_peek(PyObject *self, PyObject *args); +PyObject *debuginfo_offset(PyObject *self, PyObject *args); +PyObject *debuginfo_global(PyObject *self, PyObject *args); +PyObject *debuginfo_peek(PyObject *self, PyObject *args); /* implementations */ #ifndef PYPY_NOT_MAIN_FILE -static PyObject *debuginfo_offset(PyObject *self, PyObject *args) +PyObject *debuginfo_offset(PyObject *self, PyObject *args) { int index; if (!PyArg_ParseTuple(args, "i", &index)) @@ -30,7 +30,7 @@ return PyInt_FromLong(debuginfo_offsets[index]); } -static PyObject *debuginfo_global(PyObject *self, PyObject *args) +PyObject *debuginfo_global(PyObject *self, PyObject *args) { int index; if (!PyArg_ParseTuple(args, "i", &index)) @@ -38,7 +38,7 @@ return PyLong_FromVoidPtr(debuginfo_globals[index]); } -static PyObject *debuginfo_peek(PyObject *self, PyObject *args) +PyObject *debuginfo_peek(PyObject *self, PyObject *args) { PyObject *o; int size; 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 Oct 10 10:24:49 2005 @@ -2,16 +2,21 @@ /************************************************************/ /*** C header subsection: exceptions ***/ -#ifndef PYPY_STANDALONE - static PyObject *RPythonError; +#if !defined(PYPY_STANDALONE) && !defined(PYPY_NOT_MAIN_FILE) + PyObject *RPythonError; #endif /******************************************************************/ #ifdef HAVE_RTYPER /* RPython version of exceptions */ /******************************************************************/ -static RPYTHON_EXCEPTION_VTABLE rpython_exc_type = NULL; -static RPYTHON_EXCEPTION rpython_exc_value = NULL; +#ifdef PYPY_NOT_MAIN_FILE +extern RPYTHON_EXCEPTION_VTABLE rpython_exc_type; +extern RPYTHON_EXCEPTION rpython_exc_value; +#else +RPYTHON_EXCEPTION_VTABLE rpython_exc_type = NULL; +RPYTHON_EXCEPTION rpython_exc_value = NULL; +#endif #define RPyExceptionOccurred() (rpython_exc_type != NULL) 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 Oct 10 10:24:49 2005 @@ -66,7 +66,7 @@ #define OP_INT_MUL_OVF(x,y,r,err) \ { \ PY_LONG_LONG lr = (PY_LONG_LONG)(x) * (PY_LONG_LONG)(y); \ - r = lr; \ + r = (long)lr; \ if ((PY_LONG_LONG)r == lr); \ else FAIL_OVF(err, "integer multiplication"); \ } 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 Oct 10 10:24:49 2005 @@ -38,6 +38,11 @@ /* prototypes */ +int LL_os_open(RPyString *filename, int flag, int mode); +long LL_read_into(int fd, RPyString *buffer); +long LL_os_write(int fd, RPyString *buffer); +void LL_os_close(int fd); +int LL_os_dup(int fd); RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st); RPySTAT_RESULT* LL_os_stat(RPyString * fname); RPySTAT_RESULT* LL_os_fstat(long fd); 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 Oct 10 10:24:49 2005 @@ -18,6 +18,7 @@ identify the thread in the system */ #define RPyThreadGetIdent GetCurrentThreadId +#define RPyOpaque_INITEXPR_ThreadLock { 0, 0, NULL } typedef struct { void (*func)(void*); @@ -91,8 +92,6 @@ /************************************************************/ -#define RPyOpaque_INITEXPR_ThreadLock { 0, 0, NULL } - typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID comperand) ; From ericvrp at codespeak.net Mon Oct 10 10:28:47 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 10 Oct 2005 10:28:47 +0200 (CEST) Subject: [pypy-svn] r18325 - pypy/dist/pypy/translator/js Message-ID: <20051010082847.DAD7E27B4D@code1.codespeak.net> Author: ericvrp Date: Mon Oct 10 10:28:47 2005 New Revision: 18325 Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/opwriter.py Log: minor changes. All binaryops are now implemented. Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Mon Oct 10 10:28:47 2005 @@ -131,7 +131,7 @@ n += 1 def binaryop(self, name, targetvar, type_, ref1, ref2): - arithmetic = '*/+-%^&|' + arithmetic = ('*', '/', '+', '-', '%', '^', '&', '|', '<<', '>>') comparison = ('<', '<=', '==', '!=', '>=', '>') if name in arithmetic or name in comparison: self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Mon Oct 10 10:28:47 2005 @@ -60,11 +60,11 @@ 'ptr_ne': '!=', } - shift_operations = {'int_lshift': 'shl', - 'int_rshift': 'shr', + shift_operations = {'int_lshift': '<<', + 'int_rshift': '>>', - 'uint_lshift': 'shl', - 'uint_rshift': 'shr', + 'uint_lshift': '<<', + 'uint_rshift': '>>', } From ericvrp at codespeak.net Mon Oct 10 10:45:05 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 10 Oct 2005 10:45:05 +0200 (CEST) Subject: [pypy-svn] r18326 - pypy/dist/pypy/translator/js Message-ID: <20051010084505.4B65C27B4D@code1.codespeak.net> Author: ericvrp Date: Mon Oct 10 10:45:04 2005 New Revision: 18326 Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/opwriter.py Log: Simplification of shift operations. They no longer need to be special-cased. One more test passes. Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Mon Oct 10 10:45:04 2005 @@ -133,14 +133,11 @@ def binaryop(self, name, targetvar, type_, ref1, ref2): arithmetic = ('*', '/', '+', '-', '%', '^', '&', '|', '<<', '>>') comparison = ('<', '<=', '==', '!=', '>=', '>') - if name in arithmetic or name in comparison: + if name in arithmetic or name in comparison: #XXX this should now always true self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) else: self.llvm("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) - def shiftop(self, name, targetvar, type_, ref1, ref2): - self.llvm("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2)) - def call(self, targetvar, returntype, functionref, argrefs, argtypes, label=None, except_label=None): args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) if except_label: Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Mon Oct 10 10:45:04 2005 @@ -15,6 +15,8 @@ 'int_and': '&', 'int_or': '|', 'int_xor': '^', + 'int_lshift': '<<', + 'int_rshift': '>>', 'int_lt': '<', 'int_le': '<=', 'int_eq': '==', @@ -30,6 +32,8 @@ 'uint_and': '&', 'uint_or': '|', 'uint_xor': '^', + 'uint_lshift': '<<', + 'uint_rshift': '>>', 'uint_lt': '<', 'uint_le': '<=', 'uint_eq': '==', @@ -60,13 +64,6 @@ 'ptr_ne': '!=', } - shift_operations = {'int_lshift': '<<', - 'int_rshift': '>>', - - 'uint_lshift': '<<', - 'uint_rshift': '>>', - } - char_operations = {'char_lt': '<', 'char_le': '<=', @@ -88,8 +85,6 @@ else: if op.opname in self.binary_operations: 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_'): @@ -211,21 +206,6 @@ 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 - if isinstance(op.args[1], Constant): - tmpvar = self.db.repr_arg(op.args[1]) - else: - tmpvar = self.db.repr_tmpvar() - self.codewriter.cast(tmpvar, self.db.repr_arg_type(op.args[1]), self.db.repr_arg(op.args[1]), 'ubyte') - self.codewriter.shiftop(name, - self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), - self.db.repr_arg(op.args[0]), - tmpvar) - def cast_char_to_int(self, op): " works for all casts " assert len(op.args) == 1 From tismer at codespeak.net Mon Oct 10 15:45:10 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 10 Oct 2005 15:45:10 +0200 (CEST) Subject: [pypy-svn] r18333 - pypy/extradoc/sprintinfo Message-ID: <20051010134510.E916D27B54@code1.codespeak.net> Author: tismer Date: Mon Oct 10 15:45:09 2005 New Revision: 18333 Added: pypy/extradoc/sprintinfo/paris-2005-stackless-discussion.txt Log: added discussion about stackless Added: pypy/extradoc/sprintinfo/paris-2005-stackless-discussion.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris-2005-stackless-discussion.txt Mon Oct 10 15:45:09 2005 @@ -0,0 +1,85 @@ +==================================================== + Stackless / Continuation discussion group +==================================================== + +Bert Freudenberg, Jacob Hall?n, Adrien di Mascio, +Valentino Volonghi, Christian Tismer + +Introduction to current ideas +------------------------------ + +We had a small introduction about Stackless Python and +its implementation. We compared that to PyPy for similarities +and differences. + +The idea is to keep recursion and stack usage as an efficient +approach using the C compiler and current processor. +The whole problem of making PyPy stackless is solved by providing +RPython with a mechanism to unwind and save this stack structure. + +An implementation of an example was written by Armin. This +is thought as a template of how the generated code (c|sh)ould look like. + + +This approach supports + +- full continuations, because we can clone the saved block structures +- restartable exceptions (yet only at the RPython level) +- pickling program state +- unlimited recursion +- context switching +- garbage collection with explicit knowledge of all roots + + +General impressions +-------------------- + +The proposed stackless extension of the existing framework +might be easier to implement than a new approach using +continuation passing style. But we might want to try +examples for both and compare performance. + +Needed independently of the backend: +being able to capture variables of a block. +This could work on the annotated flowgraph, but probably makes +more sense after all the backend optimizations. It is still +the same for all backends. + +Needed action: +Find the set of necessary structures to describe the status of all blocks. +Generate types for all the variants of blocks. The concrete implementation +may vary. The current simple approach is a block number that encodes +function, arity, return type of the function and relative block +number. Different encodings are possible and may vary per backend. +(In assembly, one would probably add descriptor info right before +the function entrypoint...) + +Aliveness considerations, partially related to the backend: +The state blocks take over the role of the stack. The stack may +instead be considered as a cache for the state blocks. State +blocks are actually a synonym for continuations. + + +Backend: + +Tasks for implementation: + +- generating the structures for saving the blocks +- generate extra code for function re-entry +- write extra support for detecting stack overflows. + + + have extra info about the stack size of every function. + +Thinking about re-use of the existing exception handling code, +which is there for every function call. Adding yet another case +might be cheap. See if this is simpler or more complex +than using extra variables. + +Observations: +------------- + +We can use this mechanism to produce restartable exceptions. But this +is not about Python-level exceptions without further support. + +This approach appears to give us full continuations for free. + From hpk at codespeak.net Mon Oct 10 16:08:49 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 10 Oct 2005 16:08:49 +0200 (CEST) Subject: [pypy-svn] r18334 - pypy/extradoc/sprintinfo Message-ID: <20051010140849.4F5CA27B5B@code1.codespeak.net> Author: hpk Date: Mon Oct 10 16:08:47 2005 New Revision: 18334 Added: pypy/extradoc/sprintinfo/paris-2005-planning.txt (contents, props changed) Log: planning for today after our discussions/presenting their results Added: pypy/extradoc/sprintinfo/paris-2005-planning.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris-2005-planning.txt Mon Oct 10 16:08:47 2005 @@ -0,0 +1,54 @@ + + +Paris sprint planning +------------------------------------- + +Times (proposal): + + 10:00 - 20:00 core sprinting time + 10:30 planning session + ca. 01:00 pm lunch time + +thursday: breakday (for some of us: eu-consortium meeting) + + +pairing monday +======================= + +stackless/cps: + christian, armin + Valentino, Amaury + Adrien, Anders + +andrew/michael: powerpc-backend + +bert, samuele, boris, arre, aurelien: different specialization to more HL-backends + +llinterpreter: Carl, NN (holger later) + + +later wednesday: +discussing compiler & phase 2 work/tasks for the sprint WP09/WP10 + +peoples present +--------------------- + +armin +bert +samuele +anders +carl +boris +amory +andrew thompson +adrien +michael hudson +arre +aurelien +olivier + +Bea +Nicolas +jacob + + From cfbolz at codespeak.net Mon Oct 10 16:10:59 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 10 Oct 2005 16:10:59 +0200 (CEST) Subject: [pypy-svn] r18335 - pypy/extradoc/sprintinfo/paris Message-ID: <20051010141059.2606027B5B@code1.codespeak.net> Author: cfbolz Date: Mon Oct 10 16:10:57 2005 New Revision: 18335 Added: pypy/extradoc/sprintinfo/paris/ pypy/extradoc/sprintinfo/paris/tllinterpreter_planning.txt Log: add translatable llinterpreter planning Added: pypy/extradoc/sprintinfo/paris/tllinterpreter_planning.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris/tllinterpreter_planning.txt Mon Oct 10 16:10:57 2005 @@ -0,0 +1,63 @@ +======================================== +Translatable LLInterpreter Working Group +======================================== + +Samuele Pedroni, Anders Chrigstrom, Anders Lehmann, +Carl Friedrich Bolz, Ludovic Aubry + + +Relation to JIT work +==================== + + * give hints about arguments that should be considered constant + * assembler hard to debug / not portable + * plan is to produce low level graphs + * (to make this faster later, we could later improve this by really producing + machine code) + + +Other reasons for TLLI +====================== + + * better debugging + * enable improving the GCs + + +Requirements that follow from this +=================================== + + * it should be translatable (evidently) + * need to call functions written in C/other backend + * there must be a manipulabable memory representation of the low level graphs + * a future goal would be to be able to use the LLInterp only for parts of the + codebase -- this relates to separation of compilation + +Questions +========= + + * what to do about types? the layout has to be compatible with what the C + compilers do + - one possiblity would be to encode the types in the serialized graphs in + a platform dependent manner + * how would external function calls work? + - you would probably have to have wrapper function for every signature that + occurs + * it will probably be necessary to mix hl and ll. is that possible? + +Tasks +===== + + * support for addresses in the backends + * thinking about the memory representation of the ll graphs + * thinking about how to treat external functions + * writing the llinterp + + +Advanced topics +=============== + + * some parts of the information that the llinterpreter will need to interpret + the graphs may be messy to pass to it. so an idea would be to generate parts + of the llinterpreter as part of the rtyping process: basically a special + function saying "I'd like an llinterpreter for this function" + From cfbolz at codespeak.net Mon Oct 10 16:45:45 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 10 Oct 2005 16:45:45 +0200 (CEST) Subject: [pypy-svn] r18342 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20051010144545.2BBD227B5E@code1.codespeak.net> Author: cfbolz Date: Mon Oct 10 16:45:40 2005 New Revision: 18342 Added: pypy/dist/pypy/translator/c/src/address.h pypy/dist/pypy/translator/c/test/test_lladdresses.py Modified: pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/c/src/g_include.h Log: implement easy operations for addresses in genc Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Mon Oct 10 16:45:40 2005 @@ -1,5 +1,6 @@ import sys from pypy.rpython.lltype import * +from pypy.rpython.memory.lladdress import Address, NULL # ____________________________________________________________ # @@ -43,7 +44,11 @@ def name_unichar(value): assert type(value) is unicode and len(value) == 1 return '%d' % ord(value) - + +def name_address(value): + assert value == NULL + return 'NULL' + PrimitiveName = { Signed: name_signed, @@ -53,6 +58,7 @@ UniChar: name_unichar, Bool: name_bool, Void: name_void, + Address: name_address, } PrimitiveType = { @@ -63,6 +69,7 @@ UniChar: 'unsigned int @', Bool: 'char @', Void: 'void @', + Address: 'void* @', } PrimitiveErrorValue = { @@ -73,4 +80,5 @@ UniChar: '((unsigned) -1)', Bool: '((char) -1)', Void: '/* error */', + Address: 'NULL', } Added: pypy/dist/pypy/translator/c/src/address.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/address.h Mon Oct 10 16:45:40 2005 @@ -0,0 +1,18 @@ +/************************************************************/ +/*** C header subsection: operations between addresses ***/ + +/*** unary operations ***/ + +/*** binary operations ***/ + +#define OP_ADR_DELTA(x,y,r,err) r = ((x) - (y)) +#define OP_ADR_SUB(x,y,r,err) r = ((x) - (y)) +#define OP_ADR_ADD(x,y,r,err) r = ((x) + (y)) + +#define OP_ADR_EQ(x,y,r,err) r = ((x) == (y)) +#define OP_ADR_NE(x,y,r,err) r = ((x) != (y)) +#define OP_ADR_LE(x,y,r,err) r = ((x) <= (y)) +#define OP_ADR_GT(x,y,r,err) r = ((x) > (y)) +#define OP_ADR_LT(x,y,r,err) r = ((x) < (y)) +#define OP_ADR_GE(x,y,r,err) r = ((x) >= (y)) + 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 Oct 10 16:45:40 2005 @@ -28,6 +28,7 @@ #include "src/unichar.h" #include "src/float.h" #include "src/pyobj.h" +#include "src/address.h" /*** modules ***/ #ifdef HAVE_RTYPER /* only if we have an RTyper */ Added: pypy/dist/pypy/translator/c/test/test_lladdresses.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/test/test_lladdresses.py Mon Oct 10 16:45:40 2005 @@ -0,0 +1,7 @@ +from pypy.rpython.memory import lladdress +from pypy.translator.c.test.test_genc import compile + +def test_null(): + def f(): + return lladdress.NULL - lladdress.NULL + fc = compile(f, []) From cfbolz at codespeak.net Mon Oct 10 18:03:09 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Mon, 10 Oct 2005 18:03:09 +0200 (CEST) Subject: [pypy-svn] r18343 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20051010160309.DA7D427B5E@code1.codespeak.net> Author: cfbolz Date: Mon Oct 10 18:03:07 2005 New Revision: 18343 Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/src/address.h pypy/dist/pypy/translator/c/test/test_lladdresses.py Log: (hpk, cfbolz): finished address operations, tests Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Mon Oct 10 18:03:07 2005 @@ -541,6 +541,23 @@ def OP_KEEPALIVE(self, op, err): # xxx what should be the sematics consequences of this return "/* kept alive: %s */ ;" % self.expr(op.args[0], special_case_void=False) + #address operations + def OP_RAW_STORE(self, op, err): + addr = self.expr(op.args[0]) + TYPE = op.args[1].value + offset = self.expr(op.args[2]) + value = self.expr(op.args[3]) + typename = self.db.gettype(TYPE).replace("@", "*") #XXX help! is this the way to do it? + return "*(((%(typename)s) %(addr)s ) + %(offset)s) = %(value)s;" % locals() + + def OP_RAW_LOAD(self, op, err): + addr = self.expr(op.args[0]) + TYPE = op.args[1].value + offset = self.expr(op.args[2]) + result = self.expr(op.result) + typename = self.db.gettype(TYPE).replace("@", "*") #XXX see above + return "%(result)s = *(((%(typename)s) %(addr)s ) + %(offset)s);" % locals() + def pyobj_incref(self, v): T = self.lltypemap(v) return self.pyobj_incref_expr(LOCALVAR % v.name, T) Modified: pypy/dist/pypy/translator/c/src/address.h ============================================================================== --- pypy/dist/pypy/translator/c/src/address.h (original) +++ pypy/dist/pypy/translator/c/src/address.h Mon Oct 10 18:03:07 2005 @@ -16,3 +16,9 @@ #define OP_ADR_LT(x,y,r,err) r = ((x) < (y)) #define OP_ADR_GE(x,y,r,err) r = ((x) >= (y)) +#define OP_RAW_MALLOC(size,r,err) \ + r = (void*) malloc(size); \ + if (r == NULL) FAIL_EXCEPTION(err, PyExc_MemoryError, "out of memory");\ + +#define OP_RAW_FREE(x,r,err) free(x); +#define OP_RAW_MEMCOPY(x,y,size,r,err) memcpy(y,x,size); Modified: pypy/dist/pypy/translator/c/test/test_lladdresses.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_lladdresses.py (original) +++ pypy/dist/pypy/translator/c/test/test_lladdresses.py Mon Oct 10 18:03:07 2005 @@ -1,7 +1,74 @@ -from pypy.rpython.memory import lladdress +from pypy.rpython.memory.lladdress import * +from pypy.annotation.model import SomeAddress, SomeChar from pypy.translator.c.test.test_genc import compile def test_null(): def f(): - return lladdress.NULL - lladdress.NULL + return NULL - NULL fc = compile(f, []) + +def test_convert_to_bool(): + def f(x): + if x: + return bool(NULL) + else: + return bool(NULL + 1) + fc = compile(f, [int]) + res = fc(1) + assert isinstance(res, bool) and not res + res = fc(0) + assert isinstance(res, bool) and res + +def test_memory_access(): + def f(value): + addr = raw_malloc(16) + addr.signed[0] = value + return addr.signed[0] + fc = compile(f, [int]) + res = fc(42) + assert res == 42 + res = fc(1) + assert res == 1 + +def test_pointer_arithmetic(): + def f(offset, char): + addr = raw_malloc(10000) + same_offset = (addr + 2 * offset - offset) - addr + addr.char[offset] = char + result = (addr + same_offset).char[0] + raw_free(addr) + return result + fc = compile(f, [int, SomeChar()]) + res = fc(10, "c") + assert res == "c" + res = fc(12, "x") + assert res == "x" + +def test_pointer_arithmetic_inplace(): + def f(offset, char): + addr = raw_malloc(10000) + addr += offset + addr.char[-offset] = char + addr -= offset + return addr.char[0] + fc = compile(f, [int, SomeChar()]) + res = fc(10, "c") + assert res == "c" + +def test_raw_memcopy(): + 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 + fc = compile(f, []) + res = fc() + assert res + + From boria at codespeak.net Mon Oct 10 18:54:00 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Mon, 10 Oct 2005 18:54:00 +0200 (CEST) Subject: [pypy-svn] r18345 - in pypy/dist/pypy/rpython/ootype: . test Message-ID: <20051010165400.9A91D27B5B@code1.codespeak.net> Author: boria Date: Mon Oct 10 18:54:00 2005 New Revision: 18345 Added: pypy/dist/pypy/rpython/ootype/ (props changed) pypy/dist/pypy/rpython/ootype/__init__.py (contents, props changed) pypy/dist/pypy/rpython/ootype/ootype.py - copied, changed from r18343, pypy/dist/pypy/rpython/lltype.py pypy/dist/pypy/rpython/ootype/test/ (props changed) pypy/dist/pypy/rpython/ootype/test/test_ootype.py - copied, changed from r18343, pypy/dist/pypy/rpython/test/test_lltype.py Log: * Initial work on the high-level backend. Added: pypy/dist/pypy/rpython/ootype/__init__.py ============================================================================== From boria at codespeak.net Mon Oct 10 19:41:57 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Mon, 10 Oct 2005 19:41:57 +0200 (CEST) Subject: [pypy-svn] r18347 - in pypy/dist/pypy/rpython/ootype: . test Message-ID: <20051010174157.12E5427B56@code1.codespeak.net> Author: boria Date: Mon Oct 10 19:41:56 2005 New Revision: 18347 Modified: pypy/dist/pypy/rpython/ootype/ootype.py pypy/dist/pypy/rpython/ootype/test/test_ootype.py Log: (Boris, Samuele, Arre, Bert) * Initial tests and class implementation for high-level backend. Modified: pypy/dist/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/ootype.py Mon Oct 10 19:41:56 2005 @@ -129,8 +129,43 @@ Void = Primitive("Void", None) UniChar = Primitive("UniChar", u'\x00') +class Class(OOType): + + def __init__(self, name, superclass, fields): + self._fields = fields + + for name, defn in fields.iteritems(): + if type(defn) is not tuple: + fields[name] = (defn, defn._defl()) + # ____________________________________________________________ +class _instance(object): + + def __init__(self, CLASS): + self.__dict__["_TYPE"] = CLASS + + for name, (ootype, default) in self._TYPE._fields.iteritems(): + self.__dict__[name] = default + + def __getattr__(self, name): + try: + self._TYPE._fields[name] + except KeyError: + raise TypeError("No field named %r" % name) + + return self.__dict__[name] + + def __setattr__(self, name, value): + self.__getattr__(name) + + if self._TYPE._fields[name][0] != typeOf(value): + raise TypeError("Expected type %r" % self._TYPE._fields[name][0]) + + self.__dict__[name] = value + +def new(CLASS): + return _instance(CLASS) def typeOf(val): try: Modified: pypy/dist/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/test/test_ootype.py Mon Oct 10 19:41:56 2005 @@ -1,4 +1,23 @@ from pypy.rpython.ootype.ootype import * +import py def test_simple(): assert typeOf(1) is Signed + +def test_simple_class(): + C = Class("test", None, {"a": Signed}) + + c = new(C) + assert typeOf(c) == C + + py.test.raises(TypeError, "c.z") + py.test.raises(TypeError, "c.a = 3.0") + + c.a = 3 + assert c.a == 3 + +def test_simple_default_class(): + C = Class("test", None, {"a": (Signed, 3)}) + + c = new(C) + assert c.a == 3 From mwh at codespeak.net Mon Oct 10 19:49:36 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 10 Oct 2005 19:49:36 +0200 (CEST) Subject: [pypy-svn] r18348 - in pypy/dist/pypy/translator: . asm asm/ppcgen asm/ppcgen/test asm/test tool/pygame Message-ID: <20051010174936.BFAF327B54@code1.codespeak.net> Author: mwh Date: Mon Oct 10 19:49:28 2005 New Revision: 18348 Added: pypy/dist/pypy/translator/asm/ pypy/dist/pypy/translator/asm/__init__.py pypy/dist/pypy/translator/asm/autopath.py pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/ppcgen/ pypy/dist/pypy/translator/asm/ppcgen/__init__.py pypy/dist/pypy/translator/asm/ppcgen/_ppcgen.c pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py pypy/dist/pypy/translator/asm/ppcgen/assembler.py pypy/dist/pypy/translator/asm/ppcgen/autopath.py pypy/dist/pypy/translator/asm/ppcgen/field.py pypy/dist/pypy/translator/asm/ppcgen/form.py pypy/dist/pypy/translator/asm/ppcgen/func_builder.py pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py pypy/dist/pypy/translator/asm/ppcgen/pystructs.py pypy/dist/pypy/translator/asm/ppcgen/regname.py pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py pypy/dist/pypy/translator/asm/ppcgen/test/ pypy/dist/pypy/translator/asm/ppcgen/test/__init__.py pypy/dist/pypy/translator/asm/ppcgen/test/autopath.py pypy/dist/pypy/translator/asm/ppcgen/test/test_field.py pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py pypy/dist/pypy/translator/asm/ppcgen/util.py pypy/dist/pypy/translator/asm/test/ pypy/dist/pypy/translator/asm/test/__init__.py pypy/dist/pypy/translator/asm/test/autopath.py pypy/dist/pypy/translator/asm/test/test_asm.py Modified: pypy/dist/pypy/translator/tool/pygame/graphdisplay.py pypy/dist/pypy/translator/translator.py Log: (andrewt, mwh) very first cut of the ppc32 backend. works for a couple of toy integer using examples. hope i've disabled all the relavent tests for non-PPC :) includes an adapted version of my (mwh's) ppy package. Added: pypy/dist/pypy/translator/asm/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/__init__.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1 @@ +# ppc only for now!! Added: pypy/dist/pypy/translator/asm/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/autopath.py Mon Oct 10 19:49:28 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/translator/asm/genasm.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/genasm.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,119 @@ +from pypy.objspace.flow.model import traverse, Block, Variable, Constant +from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler +from pypy.translator.asm.ppcgen.func_builder import make_func + +def genlinkcode(link): + for s, t in zip(link.args, link.target.inputargs): + print ' ', 'mr', t, s + + +def genasm(translator): + + f = translator.entrypoint + + graph = translator.getflowgraph(f) + + g = FuncGenerator(graph) + g.gencode() + return make_func(g.assembler, 'i', 'ii') + + +class FuncGenerator(object): + + def __init__(self, graph): + self.graph = graph + self.allblocks = [] + self.blocknum = {} + def visit(block): + if isinstance(block, Block): + self.allblocks.append(block) + self.blocknum[block] = len(self.blocknum) + traverse(visit, graph) + self._var2reg = {} + self.next_register = 3 + for var in graph.startblock.inputargs: + self.assign_register(var) + self._block_counter = 0 + self.assembler = PPCAssembler() + + def assign_register(self, var): + assert var not in self._var2reg + self._var2reg[var] = self.next_register + self.next_register += 1 + + def reg(self, var): + assert isinstance(var, Variable) + if var not in self._var2reg: + self.assign_register(var) + return self._var2reg[var] + + def blockname(self): + self._block_counter += 1 + return 'anonblock' + str(self._block_counter) + + def genlinkcode(self, link): + for s, t in zip(link.args, link.target.inputargs): + self.assembler.mr(self.reg(t), self.reg(s)) + self.assembler.b('block' + str(self.blocknum[link.target])) + + def genblockcode(self, block): + self.assembler.label('block'+str(self.blocknum[block])) + for op in block.operations: + print self.reg(op.result), op, op.args + getattr(self, op.opname)(op.result, *op.args) + assert len(block.exits) in [0, 1, 2] + if len(block.exits) == 2: + assert block.exitswitch is not None + truelink, falselink = block.exits + b = self.blockname() + self.assembler.cmpwi(0, self.reg(block.exitswitch), 1) + self.assembler.bne(b) + self.genlinkcode(truelink) + self.assembler.label(b) + self.genlinkcode(falselink) + elif len(block.exits) == 1: + self.genlinkcode(block.exits[0]) + else: + self.assembler.mr(3, self.reg(block.inputargs[0])) + self.assembler.blr() + + def gencode(self): + #print map(self.reg, self.graph.startblock.inputargs) + for block in self.allblocks: + self.genblockcode(block) + + def int_add(self, dest, v1, v2): + if isinstance(v1, Constant): + self.assembler.addi(self.reg(dest), self.reg(v2), v1.value) + elif isinstance(v2, Constant): + self.assembler.addi(self.reg(dest), self.reg(v1), v2.value) + else: + self.assembler.add(self.reg(dest), self.reg(v1), self.reg(v2)) + + def int_sub(self, dest, v1, v2): + if isinstance(v1, Constant): + self.assembler.subfi(self.reg(dest), self.reg(v2), v1.value) + elif isinstance(v2, Constant): + self.assembler.addi(self.reg(dest), self.reg(v1), -v2.value) + else: + self.assembler.sub(self.reg(dest), self.reg(v1), self.reg(v2)) + + def int_gt(self, dest, v1, v2): + conditional = 'bgt' + if isinstance(v1, Constant): + conditional = 'ble' + self.assembler.cmpwi(0, self.reg(v2), v1.value) + elif isinstance(v2, Constant): + self.assembler.cmpwi(0, self.reg(v1), v2.value) + else: + self.assembler.cmpw(0, self.reg(v2), self.reg(v1)) + b = self.blockname() + self.assembler.xor(self.reg(dest), self.reg(dest), self.reg(dest)) + getattr(self.assembler, conditional)(b) + self.assembler.addi(self.reg(dest), self.reg(dest), 1) + self.assembler.label(b) + + def same_as(self, dest, v1): + self.assembler.mr(self.reg(dest), self.reg(v1)) + + Added: pypy/dist/pypy/translator/asm/ppcgen/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/asm/ppcgen/_ppcgen.c ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/_ppcgen.c Mon Oct 10 19:49:28 2005 @@ -0,0 +1,150 @@ +#include +#include + +#define __dcbf(base, index) \ + __asm__ ("dcbf %0, %1" : /*no result*/ : "b%" (index), "r" (base) : "memory") + + +static PyTypeObject* mmap_type; + +#if defined(__APPLE__) + +#include + +static PyObject* +_ppy_NSLookupAndBindSymbol(PyObject* self, PyObject* args) +{ + char *s; + NSSymbol sym; + + if (!PyArg_ParseTuple(args, "s", &s)) + return NULL; + + if (!NSIsSymbolNameDefined(s)) { + return PyErr_Format(PyExc_ValueError, + "symbol '%s' not found", s); + } + + sym = NSLookupAndBindSymbol(s); + + return PyInt_FromLong((long)NSAddressOfSymbol(sym)); +} + + +#elif defined(linux) + +#include + +static PyObject* +_ppy_dlsym(PyObject* self, PyObject* args) +{ + char *s; + void *handle; + void *sym; + + if (!PyArg_ParseTuple(args, "s", &s)) + return NULL; + + handle = dlopen(RTLD_DEFAULT, RTLD_LAZY); + sym = dlsym(handle, s); + if (sym == NULL) { + return PyErr_Format(PyExc_ValueError, + "symbol '%s' not found", s); + } + return PyInt_FromLong((long)sym); +} + +#else + +#error "OS not supported" + +#endif + + +static PyObject* +_ppy_mmap_exec(PyObject* self, PyObject* args) +{ + PyObject* code_args; + PyObject* r; + PyObject* mmap_obj; + char* code; + size_t size; + + if (!PyArg_ParseTuple(args, "O!O!:mmap_exec", + mmap_type, &mmap_obj, + &PyTuple_Type, &code_args)) + return NULL; + + code = *((char**)mmap_obj + 2); + size = *((size_t*)mmap_obj + 3); + + r = ((PyCFunction)code)(NULL, code_args); + + Py_DECREF(args); + + return r; +} + +static PyObject* +_ppy_mmap_flush(PyObject* self, PyObject* arg) +{ + char* code; + size_t size; + int i = 0; + + if (!PyObject_TypeCheck(arg, mmap_type)) { + PyErr_SetString(PyExc_TypeError, + "mmap_flush: single argument must be mmap object"); + } + + code = *((char**)arg + 2); + size = *((size_t*)arg + 3); + + for (; i < size; i += 32){ + __dcbf(code, i); + } + + Py_INCREF(Py_None); + return Py_None; +} + + +PyMethodDef _ppy_methods[] = { +#if defined(__APPLE__) + {"NSLookupAndBindSymbol", _ppy_NSLookupAndBindSymbol, + METH_VARARGS, ""}, +#elif defined(linux) + {"dlsym", _ppy_dlsym, METH_VARARGS, ""}, +#endif + {"mmap_exec", _ppy_mmap_exec, METH_VARARGS, ""}, + {"mmap_flush", _ppy_mmap_flush, METH_O, ""}, + {0, 0} +}; + +PyMODINIT_FUNC +init_ppcgen(void) +{ + PyObject* m; + PyObject* mmap_module; + PyObject* mmap_func; + PyObject* mmap_obj; + + m = Py_InitModule("_ppcgen", _ppy_methods); + + /* argh */ + /* time to campaign for a C API for the mmap module! */ + mmap_module = PyImport_ImportModule("mmap"); + if (!mmap_module) + return; + mmap_func = PyObject_GetAttrString(mmap_module, "mmap"); + if (!mmap_func) + return; + mmap_obj = PyEval_CallFunction(mmap_func, "iii", -1, 0, MAP_ANON); + if (!mmap_obj) + return; + mmap_type = mmap_obj->ob_type; + Py_INCREF(mmap_type); + Py_DECREF(mmap_obj); + Py_DECREF(mmap_func); + Py_DECREF(mmap_module); +} Added: pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,16 @@ +import py +_ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() +import mmap, struct + +class AsmCode(object): + def __init__(self, size): + self.code = mmap.mmap(-1, size, + mmap.MAP_ANON|mmap.MAP_PRIVATE, + mmap.PROT_WRITE|mmap.PROT_READ|mmap.PROT_EXEC) + def emit(self, insn): + self.code.write(struct.pack('i', insn)) + def __call__(self, *args): + return _ppcgen.mmap_exec(self.code, args) + def flush_cache(self): + _ppcgen.mmap_flush(self.code) + Added: pypy/dist/pypy/translator/asm/ppcgen/assembler.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/assembler.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,77 @@ +import array +import os +from pypy.translator.asm.ppcgen import form + +# don't be fooled by the fact that there's some separation between a +# generic assembler class and a PPC assembler class... there's +# certainly a RISC dependency in here, and quite possibly a PPC +# dependency or two too. I personally don't care :) + +class AssemblerException(Exception): + pass + +class Assembler(object): + def __init__(self): + self.insts = [] + self.labels = {} + self.rlabels = {} + + def label(self, name): + if name in self.labels: + raise AssemblerException, "duplicate label '%s'"%(name,) + self.labels[name] = len(self.insts)*4 + self.rlabels.setdefault(len(self.insts)*4, []).append(name) + + def labelname(self, base="L"): + i = 0 + while 1: + ln = base + str(i) + if ln not in self.labels: + return ln + i += 1 + + def assemble0(self, dump=os.environ.has_key('PPY_DEBUG')): + for i, inst in enumerate(self.insts): + for f in inst.lfields: + l = self.labels[inst.fields[f]] - 4*i + inst.fields[f] = l + buf = [] + for inst in self.insts: + buf.append(inst.assemble()) + if dump: + for i in range(len(buf)): + inst = self.disassemble(buf[i], self.rlabels, i*4) + for lab in self.rlabels.get(4*i, []): + print "%s:"%(lab,) + print "\t%4d %s"%(4*i, inst) + return buf + + def assemble(self, dump=os.environ.has_key('PPY_DEBUG')): + insns = self.assemble0(dump) + from pypy.translator.asm.ppcgen import asmfunc + c = asmfunc.AsmCode(len(insns)*4) + for i in insns: + c.emit(i) + c.flush_cache() + return c + + def get_idescs(cls): + r = [] + for name in dir(cls): + a = getattr(cls, name) + if isinstance(a, form.IDesc): + r.append((name, a)) + return r + get_idescs = classmethod(get_idescs) + + def disassemble(cls, inst, labels={}, pc=0): + matches = [] + idescs = cls.get_idescs() + for name, idesc in idescs: + m = idesc.match(inst) + if m > 0: + matches.append((m, idesc, name)) + if matches: + score, idesc, name = max(matches) + return idesc.disassemble(name, inst, labels, pc) + disassemble = classmethod(disassemble) Added: pypy/dist/pypy/translator/asm/ppcgen/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/autopath.py Mon Oct 10 19:49:28 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/translator/asm/ppcgen/field.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/field.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,61 @@ +# only a small file, but there's some hairy stuff in here! +""" +>>> f = Field('test', 16, 31) +>>> f + +>>> f.encode(65535) +65535 +>>> f.encode(65536) +Traceback (most recent call last): + File \"\", line 1, in ? + File \"field.py\", line 25, in encode + raise ValueError(\"field '%s' can't accept value %s\" +ValueError: field 'test' can't accept value 65536 +>>> + +""" + + +class Field(object): + def __init__(self, name, left, right, signedness=False, valclass=int): + self.name = name + self.left = left + self.right = right + width = self.right - self.left + 1 + # mask applies before shift! + self.mask = 2**width - 1 + self.signed = signedness == 'signed' + self.valclass = valclass + def __repr__(self): + return ''%(self.name,) + def encode(self, value): + if not issubclass(self.valclass, type(value)): + raise ValueError("field '%s' takes '%s's, not '%s's" + %(self.name, self.valclass.__name__, type(value).__name__)) + if not self.signed and value < 0: + raise ValueError("field '%s' is unsigned and can't accept value %d" + %(self.name, value)) + # that this does the right thing is /not/ obvious (but true!) + if ((value >> 31) ^ value) & ~(self.mask >> self.signed): + raise ValueError("field '%s' can't accept value %s" + %(self.name, value)) + value &= self.mask + value = long(value) + value <<= (32 - self.right - 1) + if value & 0x80000000L: + # yuck: + return ~int((~value)&0xFFFFFFFFL) + else: + return int(value) + def decode(self, inst): + mask = self.mask + v = (inst >> 32 - self.right - 1) & mask + if self.signed and (~mask >> 1) & mask & v: + v = ~(~v&mask) + return self.valclass(v) + def r(self, v, labels, pc): + return self.decode(v) + +if __name__=='__main__': + import doctest + doctest.testmod() Added: pypy/dist/pypy/translator/asm/ppcgen/form.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/form.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,191 @@ + +# XXX there is much grot here. + +# some of this comes from trying to present a reasonably intuitive and +# useful interface, which implies a certain amount of DWIMmery. +# things surely still could be more transparent. + +class FormException(Exception): + pass + + +class Instruction(object): + def __init__(self, fields): + self.fields = fields + self.lfields = [k for (k,v) in fields.iteritems() + if isinstance(v, str)] + if not self.lfields: + self.assemble() # for error checking only + def assemble(self): + r = 0 + for field in self.fields: + r |= field.encode(self.fields[field]) + return r + + +class IBoundDesc(object): + def __init__(self, desc, fieldmap, assembler): + self.fieldmap = fieldmap + self.desc = desc + self.assembler = assembler + def calc_fields(self, args, kw): + fieldsleft = list(self.desc.fields) + fieldvalues = {} + for fname in kw: + kw[fname] = self.fieldmap[fname] + for d in (self.desc.specializations, kw): + for field in d: + fieldsleft.remove(field) + fieldvalues[field] = d[field] + for i in range(min(len(self.desc.defaults), len(fieldsleft) - len(args))): + f, v = self.desc.defaults[i] + fieldvalues[f] = v + fieldsleft.remove(f) + for a in args: + field = fieldsleft.pop(0) + fieldvalues[field] = a + return fieldvalues, fieldsleft + def __call__(self, *args, **kw): + fieldvalues, sparefields = self.calc_fields(args, kw) + if sparefields: + raise FormException, 'fields %s left'%sparefields + self.assembler.insts.append(Instruction(fieldvalues)) + + +class IBoundDupDesc(IBoundDesc): + def calc_fields(self, args, kw): + s = super(IBoundDupDesc, self) + fieldvalues, sparefields = s.calc_fields(args, kw) + for k, v in self.desc.dupfields.iteritems(): + fieldvalues[k] = fieldvalues[v] + return fieldvalues, sparefields + + +class IDesc(object): + boundtype = IBoundDesc + def __init__(self, fieldmap, fields, specializations, boundtype=None): + self.fieldmap = fieldmap + self.fields = fields + self.specializations = specializations + self.defaults = () + if boundtype is not None: + self.boundtype = boundtype + for field in specializations: + if field not in fields: + raise FormException, field + + def __get__(self, ob, cls=None): + if ob is None: return self + return self.boundtype(self, self.fieldmap, ob) + + def default(self, **defs): + assert len(defs) == 1 + f, v = defs.items()[0] + self.defaults = self.defaults + ((self.fieldmap[f], v),) + return self + + def __call__(self, **more_specializatons): + s = self.specializations.copy() + ms = {} + ds = {} + for fname, v in more_specializatons.iteritems(): + field = self.fieldmap[fname] + if field not in self.fields: + raise FormException, "don't know about '%s' here"%k + if isinstance(v, str): + ds[field] = self.fieldmap[v] + else: + ms[field] = v + s.update(ms) + if len(s) != len(self.specializations) + len(ms): + raise FormException, "respecialization not currently allowed" + if ds: + fields = list(self.fields) + for field in ds: + fields.remove(field) + return IDupDesc(self.fieldmap, tuple(fields), s, ds) + else: + r = IDesc(self.fieldmap, self.fields, s, self.boundtype) + r.defaults = tuple([(f, d) for (f, d) in self.defaults if f not in s]) + return r + + def match(self, inst): + c = 0 + for field in self.fields: + if field in self.specializations: + if field.decode(inst) != self.specializations[field]: + return 0 + else: + c += 1 + return c + + def __repr__(self): + l = [] + for field in self.fields: + if field in self.specializations: + l.append('%s=%r'%(field.name, self.specializations[field])) + else: + l.append(field.name) + r = '%s(%s)'%(self.__class__.__name__, ', '.join(l)) + if self.boundtype is not self.__class__.boundtype: + r += ' => ' + self.boundtype.__name__ + return r + + def disassemble(self, name, inst, labels, pc): + kws = [] + for field in self.fields: + if field not in self.specializations: + v = field.decode(inst) + for f, d in self.defaults: + if f is field: + if d == v: + break + else: + kws.append('%s=%s'%(field.name, field.r(inst, labels, pc))) + return "%-5s %s"%(name, ', '.join(kws)) + + +class IDupDesc(IDesc): + boundtype = IBoundDupDesc + def __init__(self, fieldmap, fields, specializations, dupfields): + super(IDupDesc, self).__init__(fieldmap, fields, specializations) + self.dupfields = dupfields + + def match(self, inst): + for field in self.dupfields: + df = self.dupfields[field] + if field.decode(inst) != df.decode(inst): + return 0 + else: + return super(IDupDesc, self).match(inst) + + +class Form(object): + fieldmap = None + def __init__(self, *fnames): + self.fields = [] + bits = {} + for fname in fnames: + if isinstance(fname, str): + field = self.fieldmap[fname] + else: + field = fname + for b in range(field.left, field.right+1): + if b in bits: + raise FormException, "'%s' and '%s' clash at bit '%s'"%( + bits[b], fname, b) + else: + bits[b] = fname + self.fields.append(field) + + def __call__(self, **specializations): + s = {} + for fname in specializations: + field = self.fieldmap[fname] + if field not in self.fields: + raise FormException, "no nothin bout '%s'"%k + s[field] = specializations[fname] + return IDesc(self.fieldmap, self.fields, s) + + def __repr__(self): + return '%s(%r)'%(self.__class__.__name__, [f.name for f in self.fields]) Added: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,158 @@ +from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler +from pypy.translator.asm.ppcgen.symbol_lookup import lookup +from pypy.translator.asm.ppcgen.regname import * + +def load_arg(code, argi, typecode): + rD = r3+argi + code.lwz(rD, r4, 12 + 4*argi) + if typecode == 'i': + code.load_word(r0, lookup("PyInt_Type")) + code.lwz(r15, rD, 4) # XXX ick! + code.cmpw(r0, r15) + code.bne("argserror") + code.lwz(rD, rD, 8) + elif typecode == 'f': + code.load_word(r0, lookup("PyFloat_Type")) + code.lwz(r15, rD, 4) + code.cmpw(r0, r15) + code.bne("argserror") + code.lfd(rD-2, rD, 8) + elif typecode != "O": + raise Exception, "erk" + +FAST_ENTRY_LABEL = "FAST-ENTRY-LABEL" + +def make_func(code, retcode, signature): + """code shouldn't contain prologue/epilogue (or touch r31)""" + + argcount = len(signature) + + ourcode = MyPPCAssembler() + ourcode.mflr(r0) + ourcode.stmw(r31, r1, -4) + ourcode.stw(r0, r1, 8) + ourcode.stwu(r1, r1, -80) + + ourcode.lwz(r3, r4, 8) + ourcode.cmpwi(r3, argcount) + ourcode.bne("argserror") + + assert argcount < 9 + + if argcount > 0: + load_arg(ourcode, 0, signature[0]) + for i in range(2, argcount): + load_arg(ourcode, i, signature[i]) + if argcount > 1: + load_arg(ourcode, 1, signature[1]) + + ourcode.bl(FAST_ENTRY_LABEL) + + if retcode == 'i': + s = lookup("PyInt_FromLong") + ourcode.load_word(r0, s) + ourcode.mtctr(r0) + ourcode.bctrl() + elif retcode == 'f': + s = lookup("PyFloat_FromDouble") + ourcode.load_word(r0, s) + ourcode.mtctr(r0) + ourcode.bctrl() + + ourcode.label("epilogue") + ourcode.lwz(r0, r1, 88) + ourcode.addi(r1, r1, 80) + ourcode.mtlr(r0) + ourcode.lmw(r31, r1, -4) + ourcode.blr() + + err_set = lookup("PyErr_SetObject") + exc = lookup("PyExc_TypeError") + + ourcode.label("argserror") + ourcode.load_word(r5, err_set) + ourcode.mtctr(r5) + ourcode.load_from(r3, exc) + ourcode.mr(r4, r3) + ourcode.bctrl() + + ourcode.li(r3, 0) + ourcode.b("epilogue") + + ourcode.label(FAST_ENTRY_LABEL) + # err, should be an Assembler method: + l = code.labels.copy() + for k in l: + l[k] += 4*len(ourcode.insts) + r = code.rlabels.copy() + for k in code.rlabels: + r[k + 4*len(ourcode.insts)] = code.rlabels[k] + ourcode.insts.extend(code.insts) + ourcode.labels.update(l) + ourcode.rlabels.update(r) + + r = ourcode.assemble() + r.FAST_ENTRY_LABEL = ourcode.labels[FAST_ENTRY_LABEL] + return r + +def wrap(funcname, retcode, signature): + + argcount = len(signature) + + ourcode = MyPPCAssembler() + ourcode.mflr(r0) + ourcode.stmw(r31, r1, -4) + ourcode.stw(r0, r1, 8) + ourcode.stwu(r1, r1, -80) + + ourcode.lwz(r3, r4, 8) + ourcode.cmpwi(r3, argcount) + ourcode.bne("argserror") + + assert argcount < 9 + + if argcount > 0: + load_arg(ourcode, 0, signature[0]) + for i in range(2, argcount): + load_arg(ourcode, i, signature[i]) + if argcount > 1: + load_arg(ourcode, 1, signature[1]) + + + ourcode.load_word(r0, lookup(funcname)) + ourcode.mtctr(r0) + ourcode.bctrl() + + if retcode == 'i': + s = lookup("PyInt_FromLong") + ourcode.load_word(r0, s) + ourcode.mtctr(r0) + ourcode.bctrl() + elif retcode == 'f': + s = lookup("PyFloat_FromDouble") + ourcode.load_word(r0, s) + ourcode.mtctr(r0) + ourcode.bctrl() + + ourcode.label("epilogue") + ourcode.lwz(r0, r1, 88) + ourcode.addi(r1, r1, 80) + ourcode.mtlr(r0) + ourcode.lmw(r31, r1, -4) + ourcode.blr() + + err_set = lookup("PyErr_SetObject") + exc = lookup("PyExc_TypeError") + + ourcode.label("argserror") + ourcode.load_word(r5, err_set) + ourcode.mtctr(r5) + ourcode.load_from(r3, exc) + ourcode.mr(r4, r3) + ourcode.bctrl() + + ourcode.li(r3, 0) + ourcode.b("epilogue") + + return ourcode.assemble() + Added: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,788 @@ +import array +from pypy.translator.asm.ppcgen.ppc_form import PPCForm as Form +from pypy.translator.asm.ppcgen.ppc_field import ppc_fields +from pypy.translator.asm.ppcgen.assembler import Assembler +from pypy.translator.asm.ppcgen.symbol_lookup import lookup + +A = Form("frD", "frA", "frB", "XO3", "Rc") +A1 = Form("frD", "frB", "XO3", "Rc") +A2 = Form("frD", "frA", "frC", "XO3", "Rc") +A3 = Form("frD", "frA", "frC", "frB", "XO3", "Rc") + +I = Form("LI", "AA", "LK") + +B = Form("BO", "BI", "BD", "AA", "LK") + +SC = Form("AA") # fudge + +DD = Form("rD", "rA", "SIMM") +DS = Form("rA", "rS", "UIMM") + +X = Form("XO1") +XS = Form("rA", "rS", "rB", "XO1", "Rc") +XS0 = Form("rS", "rA", "rB", "XO1") +XD = Form("rD", "rA", "rB", "XO1") +XO = Form("rD", "rA", "rB", "OE", "XO2", "Rc") +XO0 = Form("rD", "rA", "OE", "XO2", "Rc") +XDB = Form("frD", "frB", "XO1", "Rc") +XS0 = Form("rA", "rS", "XO1", "Rc") +X0 = Form("rA", "rB", "XO1") +XcAB = Form("crfD", "rA", "rB", "XO1") +XN = Form("rD", "rA", "NB", "XO1") +XL = Form("crbD", "crbA", "crbB", "XO1") +XL1 = Form("crfD", "crfS") +XL2 = Form("crbD", "XO1", "Rc") +XFL = Form("FM", "frB", "XO1", "Rc") +XFX = Form("CRM", "rS", "XO1") + +MI = Form("rS", "rA", "SH", "MB", "ME", "Rc") +MB = Form("rS", "rA", "rB", "MB", "ME", "Rc") + + +class BasicPPCAssembler(Assembler): + + def disassemble(cls, inst, labels={}, pc=0): + cache = cls.__dict__.get('idesc cache') + if cache is None: + idescs = cls.get_idescs() + cache = {} + for n, i in idescs: + cache.setdefault(i.specializations[ppc_fields['opcode']], + []).append((n,i)) + setattr(cls, 'idesc cache', cache) + matches = [] + idescs = cache[ppc_fields['opcode'].decode(inst)] + for name, idesc in idescs: + m = idesc.match(inst) + if m > 0: + matches.append((m, idesc, name)) + if matches: + score, idesc, name = max(matches) + return idesc.disassemble(name, inst, labels, pc) + disassemble = classmethod(disassemble) + + # "basic" means no simplified mnemonics + + # I form + b = I(18, AA=0, LK=0) + ba = I(18, AA=1, LK=0) + bl = I(18, AA=0, LK=1) + bla = I(18, AA=1, LK=1) + + # B form + bc = B(16, AA=0, LK=0) + bcl = B(16, AA=0, LK=1) + bca = B(16, AA=1, LK=0) + bcla = B(16, AA=1, LK=1) + + # SC form + sc = SC(17, AA=1) # it's not really the aa field... + + # D form + addi = DD(14) + addic = DD(12) + addicx = DD(13) + addis = DD(15) + + andix = DS(28) + andisx = DS(29) + + cmpi = Form("crfD", "L", "rA", "SIMM")(11) + cmpi.default(L=0).default(crfD=0) + cmpli = Form("crfD", "L", "rA", "UIMM")(10) + cmpli.default(L=0).default(crfD=0) + + lbz = DD(34) + lbzu = DD(35) + lfd = DD(50) + lfdu = DD(51) + lfs = DD(48) + lfsu = DD(49) + lha = DD(42) + lhau = DD(43) + lhz = DD(40) + lhzu = DD(41) + lmw = DD(46) + lwz = DD(32) + lwzu = DD(33) + + mulli = DD(7) + ori = DS(24) + oris = DS(25) + + stb = DD(38) + stbu = DD(39) + stfd = DD(54) + stfdu = DD(55) + stfs = DD(52) + stfsu = DD(53) + sth = DD(44) + sthu = DD(45) + stmw = DD(47) + stw = DD(36) + stwu = DD(37) + + subfic = DD(8) + twi = Form("TO", "rA", "SIMM")(3) + xori = DS(26) + xoris = DS(27) + + # X form + + and_ = XS(31, XO1=28, Rc=0) + and_x = XS(31, XO1=28, Rc=1) + + andc_ = XS(31, XO1=60, Rc=0) + andc_x = XS(31, XO1=60, Rc=1) + + # is the L bit for 64 bit compares? hmm + cmp = Form("crfD", "L", "rA", "rB", "XO1")(31, XO1=0) + cmp.default(L=0).default(crfD=0) + cmpl = Form("crfD", "L", "rA", "rB", "XO1")(31, XO1=32) + cmpl.default(L=0).default(crfD=0) + + cntlzw = XS0(31, XO1=26, Rc=0) + cntlzwx = XS0(31, XO1=26, Rc=1) + + dcba = X0(31, XO1=758) + dcbf = X0(31, XO1=86) + dcbi = X0(31, XO1=470) + dcbst = X0(31, XO1=54) + dcbt = X0(31, XO1=278) + dcbtst = X0(31, XO1=246) + dcbz = X0(31, XO1=1014) + + eciwx = XD(31, XO1=310) + ecowx = XS(31, XO1=438, Rc=0) + + eieio = X(31, XO1=854) + + eqv = XS(31, XO1=284, Rc=0) + eqvx = XS(31, XO1=284, Rc=1) + + extsb = XS0(31, XO1=954, Rc=0) + extsbx = XS0(31, XO1=954, Rc=1) + + extsh = XS0(31, XO1=922, Rc=0) + extshx = XS0(31, XO1=922, Rc=1) + + fabs = XDB(63, XO1=264, Rc=0) + fabsx = XDB(63, XO1=264, Rc=1) + + fcmpo = XcAB(63, XO1=32) + fcmpu = XcAB(63, XO1=0) + + fctiw = XDB(63, XO1=14, Rc=0) + fctiwx = XDB(63, XO1=14, Rc=1) + + fctiwz = XDB(63, XO1=14, Rc=0) + fctiwzx = XDB(63, XO1=14, Rc=1) + + fmr = XDB(63, XO1=72, Rc=0) + fmrx = XDB(63, XO1=72, Rc=1) + + fnabs = XDB(63, XO1=136, Rc=0) + fnabsx = XDB(63, XO1=136, Rc=1) + + fneg = XDB(63, XO1=40, Rc=0) + fnegx = XDB(63, XO1=40, Rc=1) + + frsp = XDB(63, XO1=12, Rc=0) + frspx = XDB(63, XO1=12, Rc=1) + + fsqrt = XDB(63, XO1=22, Rc=0) + + icbi = X0(31, XO1=982) + + lbzux = XD(31, XO1=119) + lbzx = XD(31, XO1=87) + lfdux = XD(31, XO1=631) + lfdx = XD(31, XO1=599) + lfsux = XD(31, XO1=567) + lfsx = XD(31, XO1=535) + lhaux = XD(31, XO1=375) + lhax = XD(31, XO1=343) + lhbrx = XD(31, XO1=790) + lhzux = XD(31, XO1=311) + lhzx = XD(31, XO1=279) + lswi = XD(31, XO1=597) + lswx = XD(31, XO1=533) + lwarx = XD(31, XO1=20) + lwbrx = XD(31, XO1=534) + lwzux = XD(31, XO1=55) + lwzx = XD(31, XO1=23) + + mcrfs = Form("crfD", "crfS", "XO1")(63, XO1=64) + mcrxr = Form("crfD", "XO1")(31, XO1=512) + mfcr = Form("rD", "XO1")(31, XO1=19) + mffs = Form("frD", "XO1", "Rc")(63, XO1=583, Rc=0) + mffsx = Form("frD", "XO1", "Rc")(63, XO1=583, Rc=1) + mfmsr = Form("rD", "XO1")(31, XO1=83) + mfsr = Form("rD", "SR", "XO1")(31, XO1=595) + mfsrin = XDB(31, XO1=659, Rc=0) + + add = XO(31, XO2=266, OE=0, Rc=0) + addx = XO(31, XO2=266, OE=0, Rc=1) + addo = XO(31, XO2=266, OE=1, Rc=0) + addox = XO(31, XO2=266, OE=1, Rc=1) + + addc = XO(31, XO2=10, OE=0, Rc=0) + addcx = XO(31, XO2=10, OE=0, Rc=1) + addco = XO(31, XO2=10, OE=1, Rc=0) + addcox = XO(31, XO2=10, OE=1, Rc=1) + + adde = XO(31, XO2=138, OE=0, Rc=0) + addex = XO(31, XO2=138, OE=0, Rc=1) + addeo = XO(31, XO2=138, OE=1, Rc=0) + addeox = XO(31, XO2=138, OE=1, Rc=1) + + addme = XO(31, rB=0, XO2=234, OE=0, Rc=0) + addmex = XO(31, rB=0, XO2=234, OE=0, Rc=1) + addmeo = XO(31, rB=0, XO2=234, OE=1, Rc=0) + addmeox = XO(31, rB=0, XO2=234, OE=1, Rc=1) + + addze = XO(31, rB=0, XO2=202, OE=0, Rc=0) + addzex = XO(31, rB=0, XO2=202, OE=0, Rc=1) + addzeo = XO(31, rB=0, XO2=202, OE=1, Rc=0) + addzeox = XO(31, rB=0, XO2=202, OE=1, Rc=1) + + bcctr = Form("BO", "BI", "XO1", "LK")(19, XO1=528, LK=0) + bcctrl = Form("BO", "BI", "XO1", "LK")(19, XO1=528, LK=1) + + bclr = Form("BO", "BI", "XO1", "LK")(19, XO1=16, LK=0) + bclrl = Form("BO", "BI", "XO1", "LK")(19, XO1=16, LK=1) + + crand = XL(19, XO1=257) + crandc = XL(19, XO1=129) + creqv = XL(19, XO1=289) + crnand = XL(19, XO1=225) + crnor = XL(19, XO1=33) + cror = XL(19, XO1=449) + crorc = XL(19, XO1=417) + crxor = XL(19, XO1=193) + + divw = XO(31, XO2=491, OE=0, Rc=0) + divwx = XO(31, XO2=491, OE=0, Rc=1) + divwo = XO(31, XO2=491, OE=1, Rc=0) + divwox = XO(31, XO2=491, OE=1, Rc=1) + + divwu = XO(31, XO2=459, OE=0, Rc=0) + divwux = XO(31, XO2=459, OE=0, Rc=1) + divwuo = XO(31, XO2=459, OE=1, Rc=0) + divwuox = XO(31, XO2=459, OE=1, Rc=1) + + fadd = A(63, XO3=21, Rc=0) + faddx = A(63, XO3=21, Rc=1) + fadds = A(59, XO3=21, Rc=0) + faddsx = A(59, XO3=21, Rc=1) + + fdiv = A(63, XO3=18, Rc=0) + fdivx = A(63, XO3=18, Rc=1) + fdivs = A(59, XO3=18, Rc=0) + fdivsx = A(59, XO3=18, Rc=1) + + fmadd = A3(63, XO3=19, Rc=0) + fmaddx = A3(63, XO3=19, Rc=1) + fmadds = A3(59, XO3=19, Rc=0) + fmaddsx = A3(59, XO3=19, Rc=1) + + fmsub = A3(63, XO3=28, Rc=0) + fmsubx = A3(63, XO3=28, Rc=1) + fmsubs = A3(59, XO3=28, Rc=0) + fmsubsx = A3(59, XO3=28, Rc=1) + + fmul = A2(63, XO3=25, Rc=0) + fmulx = A2(63, XO3=25, Rc=1) + fmuls = A2(59, XO3=25, Rc=0) + fmulsx = A2(59, XO3=25, Rc=1) + + fnmadd = A3(63, XO3=31, Rc=0) + fnmaddx = A3(63, XO3=31, Rc=1) + fnmadds = A3(59, XO3=31, Rc=0) + fnmaddsx = A3(59, XO3=31, Rc=1) + + fnmsub = A3(63, XO3=30, Rc=0) + fnmsubx = A3(63, XO3=30, Rc=1) + fnmsubs = A3(59, XO3=30, Rc=0) + fnmsubsx = A3(59, XO3=30, Rc=1) + + fres = A1(59, XO3=24, Rc=0) + fresx = A1(59, XO3=24, Rc=1) + + frsp = A1(63, XO3=12, Rc=0) + frspx = A1(63, XO3=12, Rc=1) + + frsqrte = A1(63, XO3=26, Rc=0) + frsqrtex = A1(63, XO3=26, Rc=1) + + fsel = A3(63, XO3=23, Rc=0) + fselx = A3(63, XO3=23, Rc=1) + + frsqrt = A1(63, XO3=22, Rc=0) + frsqrtx = A1(63, XO3=22, Rc=1) + frsqrts = A1(59, XO3=22, Rc=0) + frsqrtsx = A1(59, XO3=22, Rc=1) + + fsub = A(63, XO3=20, Rc=0) + fsubx = A(63, XO3=20, Rc=1) + fsubs = A(59, XO3=20, Rc=0) + fsubsx = A(59, XO3=20, Rc=1) + + isync = X(19, XO1=150) + + mcrf = XL1(19) + + mfspr = Form("rD", "spr", "XO1")(31, XO1=339) + mftb = Form("rD", "spr", "XO1")(31, XO1=371) + + mtcrf = XFX(31, XO1=144) + + mtfsb0 = XL2(63, XO1=70, Rc=0) + mtfsb0x = XL2(63, XO1=70, Rc=1) + mtfsb1 = XL2(63, XO1=38, Rc=0) + mtfsb1x = XL2(63, XO1=38, Rc=1) + + mtfsf = XFL(63, XO1=711, Rc=0) + mtfsfx = XFL(63, XO1=711, Rc=1) + + mtfsfi = Form("crfD", "IMM", "XO1", "Rc")(63, XO1=134, Rc=0) + mtfsfix = Form("crfD", "IMM", "XO1", "Rc")(63, XO1=134, Rc=1) + + mtmsr = Form("rS", "XO1")(31, XO1=146) + + mtspr = Form("rS", "spr", "XO1")(31, XO1=467) + + mtsr = Form("rS", "SR", "XO1")(31, XO1=210) + mtsrin = Form("rS", "rB", "XO1")(31, XO1=242) + + mulhw = XO(31, OE=0, XO2=75, Rc=0) + mulhwx = XO(31, OE=0, XO2=75, Rc=1) + + mulhwu = XO(31, OE=0, XO2=11, Rc=0) + mulhwux = XO(31, OE=0, XO2=11, Rc=1) + + mullw = XO(31, OE=0, XO2=235, Rc=0) + mullwx = XO(31, OE=0, XO2=235, Rc=1) + mullwo = XO(31, OE=1, XO2=235, Rc=0) + mullwox = XO(31, OE=1, XO2=235, Rc=1) + + nand = XS(31, XO1=476, Rc=0) + nandx = XS(31, XO1=476, Rc=1) + + neg = XO0(31, OE=0, XO2=104, Rc=0) + negx = XO0(31, OE=0, XO2=104, Rc=1) + nego = XO0(31, OE=1, XO2=104, Rc=0) + negox = XO0(31, OE=1, XO2=104, Rc=1) + + nor = XS(31, XO1=124, Rc=0) + norx = XS(31, XO1=124, Rc=1) + + or_ = XS(31, XO1=444, Rc=0) + or_x = XS(31, XO1=444, Rc=1) + + orc = XS(31, XO1=412, Rc=0) + orcx = XS(31, XO1=412, Rc=1) + + rfi = X(19, XO1=50) + + rlwimi = MI(20, Rc=0) + rlwimix = MI(20, Rc=1) + + rlwinm = MI(20, Rc=0) + rlwinmx = MI(20, Rc=1) + + rlwnm = MB(23, Rc=0) + rlwnmx = MB(23, Rc=1) + + slw = XS(31, XO1=24, Rc=0) + slwx = XS(31, XO1=24, Rc=1) + + sraw = XS(31, XO1=792, Rc=0) + srawx = XS(31, XO1=792, Rc=1) + + srawi = Form("rA", "rS", "SH", "XO1", "Rc")(31, XO1=824, Rc=0) + srawix = Form("rA", "rS", "SH", "XO1", "Rc")(31, XO1=824, Rc=1) + + srw = XS(31, XO1=536, Rc=0) + srwx = XS(31, XO1=536, Rc=1) + + stbux = XS0(31, XO1=247) + stbx = XS0(31, XO1=215) + stfdux = XS0(31, XO1=759) + stfdx = XS0(31, XO1=727) + stfiwx = XS0(31, XO1=983) + stfsux = XS0(31, XO1=695) + stfsx = XS0(31, XO1=663) + sthbrx = XS0(31, XO1=918) + sthux = XS0(31, XO1=439) + sthx = XS0(31, XO1=407) + stswi = Form("rS", "rA", "NB", "XO1")(31, XO1=725) + stswx = XS0(31, XO1=661) + stwbrx = XS0(31, XO1=662) + stwcxx = Form("rS", "rA", "rB", "XO1", "Rc")(31, XO1=150, Rc=1) + stwux = XS0(31, XO1=183) + stwx = XS0(31, XO1=151) + + subf = XO(31, XO2=40, OE=0, Rc=0) + subfx = XO(31, XO2=40, OE=0, Rc=1) + subfo = XO(31, XO2=40, OE=1, Rc=0) + subfox = XO(31, XO2=40, OE=1, Rc=1) + + subfc = XO(31, XO2=8, OE=0, Rc=0) + subfcx = XO(31, XO2=8, OE=0, Rc=1) + subfco = XO(31, XO2=8, OE=1, Rc=0) + subfcox = XO(31, XO2=8, OE=1, Rc=1) + + subfe = XO(31, XO2=136, OE=0, Rc=0) + subfex = XO(31, XO2=136, OE=0, Rc=1) + subfeo = XO(31, XO2=136, OE=1, Rc=0) + subfeox = XO(31, XO2=136, OE=1, Rc=1) + + subfme = XO0(31, OE=0, XO2=232, Rc=0) + subfmex = XO0(31, OE=0, XO2=232, Rc=1) + subfmeo = XO0(31, OE=1, XO2=232, Rc=0) + subfmeox= XO0(31, OE=1, XO2=232, Rc=1) + + subfze = XO0(31, OE=0, XO2=200, Rc=0) + subfzex = XO0(31, OE=0, XO2=200, Rc=1) + subfzeo = XO0(31, OE=1, XO2=200, Rc=0) + subfzeox= XO0(31, OE=1, XO2=200, Rc=1) + + sync = X(31, XO1=598) + + tlbia = X(31, XO1=370) + tlbie = Form("rB", "XO1")(31, XO1=306) + tlbsync = X(31, XO1=566) + + tw = Form("TO", "rA", "rB", "XO1")(31, XO1=4) + + xor = XS(31, XO1=316, Rc=0) + xorx = XS(31, XO1=316, Rc=1) + +class PPCAssembler(BasicPPCAssembler): + BA = BasicPPCAssembler + + # awkward mnemonics: + # mftb + # most of the branch mnemonics... + + # F.2 Simplified Mnemonics for Subtract Instructions + + def subi(self, rD, rA, value): + self.addi(rD, rA, -value) + def subis(self, rD, rA, value): + self.addis(rD, rA, -value) + def subic(self, rD, rA, value): + self.addic(rD, rA, -value) + def subicx(self, rD, rA, value): + self.addicx(rD, rA, -value) + + def sub(self, rD, rA, rB): + self.subf(rD, rB, rA) + def subc(self, rD, rA, rB): + self.subfc(rD, rB, rA) + def subx(self, rD, rA, rB): + self.subfx(rD, rB, rA) + def subcx(self, rD, rA, rB): + self.subfcx(rD, rB, rA) + def subo(self, rD, rA, rB): + self.subfo(rD, rB, rA) + def subco(self, rD, rA, rB): + self.subfco(rD, rB, rA) + def subox(self, rD, rA, rB): + self.subfox(rD, rB, rA) + def subcox(self, rD, rA, rB): + self.subfcox(rD, rB, rA) + + # F.3 Simplified Mnemonics for Compare Instructions + + cmpwi = BA.cmpi(L=0) + cmplwi = BA.cmpli(L=0) + cmpw = BA.cmp(L=0) + cmplw = BA.cmpl(L=0) + + # what's the point? + + # F.4 Simplified Mnemonics for Rotate and Shift Instructions + + + + # F.5 Simplified Mnemonics for Branch Instructions + + # there's a lot of these! + bt = BA.bc(BO=12) + bf = BA.bc(BO=4) + bdnz = BA.bc(BO=16, BI=0) + bdnzt = BA.bc(BO=8) + bdnzf = BA.bc(BO=0) + bdz = BA.bc(BO=18) + bdzt = BA.bc(BO=10) + bdzf = BA.bc(BO=2) + + bta = BA.bca(BO=12) + bfa = BA.bca(BO=4) + bdnza = BA.bca(BO=16, BI=0) + bdnzta = BA.bca(BO=8) + bdnzfa = BA.bca(BO=0) + bdza = BA.bca(BO=18) + bdzta = BA.bca(BO=10) + bdzfa = BA.bca(BO=2) + + btl = BA.bcl(BO=12) + bfl = BA.bcl(BO=4) + bdnzl = BA.bcl(BO=16, BI=0) + bdnztl = BA.bcl(BO=8) + bdnzfl = BA.bcl(BO=0) + bdzl = BA.bcl(BO=18) + bdztl = BA.bcl(BO=10) + bdzfl = BA.bcl(BO=2) + + btla = BA.bcla(BO=12) + bfla = BA.bcla(BO=4) + bdnzla = BA.bcla(BO=16, BI=0) + bdnztla = BA.bcla(BO=8) + bdnzfla = BA.bcla(BO=0) + bdzla = BA.bcla(BO=18) + bdztla = BA.bcla(BO=10) + bdzfla = BA.bcla(BO=2) + + blr = BA.bclr(BO=20, BI=0) + btlr = BA.bclr(BO=12) + bflr = BA.bclr(BO=4) + bdnzlr = BA.bclr(BO=16, BI=0) + bdnztlr = BA.bclr(BO=8) + bdnzflr = BA.bclr(BO=0) + bdzlr = BA.bclr(BO=18, BI=0) + bdztlr = BA.bclr(BO=10) + bdzflr = BA.bclr(BO=2) + + bctr = BA.bcctr(BO=20, BI=0) + btctr = BA.bcctr(BO=12) + bfctr = BA.bcctr(BO=4) + + blrl = BA.bclrl(BO=20, BI=0) + btlrl = BA.bclrl(BO=12) + bflrl = BA.bclrl(BO=4) + bdnzlrl = BA.bclrl(BO=16, BI=0) + bdnztlrl = BA.bclrl(BO=8) + bdnzflrl = BA.bclrl(BO=0) + bdzlrl = BA.bclrl(BO=18, BI=0) + bdztlrl = BA.bclrl(BO=10) + bdzflrl = BA.bclrl(BO=2) + + bctrl = BA.bcctrl(BO=20, BI=0) + btctrl = BA.bcctrl(BO=12) + bfctrl = BA.bcctrl(BO=4) + + # these should/could take a[n optional] crf argument, but it's a + # bit hard to see how to arrange that. + + blt = BA.bc(BO=12, BI=0) + ble = BA.bc(BO=4, BI=1) + beq = BA.bc(BO=12, BI=2) + bge = BA.bc(BO=4, BI=0) + bgt = BA.bc(BO=12, BI=1) + bnl = BA.bc(BO=4, BI=0) + bne = BA.bc(BO=4, BI=2) + bng = BA.bc(BO=4, BI=1) + bso = BA.bc(BO=12, BI=3) + bns = BA.bc(BO=4, BI=3) + bun = BA.bc(BO=12, BI=3) + bnu = BA.bc(BO=4, BI=3) + + blta = BA.bca(BO=12, BI=0) + blea = BA.bca(BO=4, BI=1) + beqa = BA.bca(BO=12, BI=2) + bgea = BA.bca(BO=4, BI=0) + bgta = BA.bca(BO=12, BI=1) + bnla = BA.bca(BO=4, BI=0) + bnea = BA.bca(BO=4, BI=2) + bnga = BA.bca(BO=4, BI=1) + bsoa = BA.bca(BO=12, BI=3) + bnsa = BA.bca(BO=4, BI=3) + buna = BA.bca(BO=12, BI=3) + bnua = BA.bca(BO=4, BI=3) + + bltl = BA.bcl(BO=12, BI=0) + blel = BA.bcl(BO=4, BI=1) + beql = BA.bcl(BO=12, BI=2) + bgel = BA.bcl(BO=4, BI=0) + bgtl = BA.bcl(BO=12, BI=1) + bnll = BA.bcl(BO=4, BI=0) + bnel = BA.bcl(BO=4, BI=2) + bngl = BA.bcl(BO=4, BI=1) + bsol = BA.bcl(BO=12, BI=3) + bnsl = BA.bcl(BO=4, BI=3) + bunl = BA.bcl(BO=12, BI=3) + bnul = BA.bcl(BO=4, BI=3) + + bltla = BA.bcla(BO=12, BI=0) + blela = BA.bcla(BO=4, BI=1) + beqla = BA.bcla(BO=12, BI=2) + bgela = BA.bcla(BO=4, BI=0) + bgtla = BA.bcla(BO=12, BI=1) + bnlla = BA.bcla(BO=4, BI=0) + bnela = BA.bcla(BO=4, BI=2) + bngla = BA.bcla(BO=4, BI=1) + bsola = BA.bcla(BO=12, BI=3) + bnsla = BA.bcla(BO=4, BI=3) + bunla = BA.bcla(BO=12, BI=3) + bnula = BA.bcla(BO=4, BI=3) + + bltlr = BA.bclr(BO=12, BI=0) + blelr = BA.bclr(BO=4, BI=1) + beqlr = BA.bclr(BO=12, BI=2) + bgelr = BA.bclr(BO=4, BI=0) + bgtlr = BA.bclr(BO=12, BI=1) + bnllr = BA.bclr(BO=4, BI=0) + bnelr = BA.bclr(BO=4, BI=2) + bnglr = BA.bclr(BO=4, BI=1) + bsolr = BA.bclr(BO=12, BI=3) + bnslr = BA.bclr(BO=4, BI=3) + bunlr = BA.bclr(BO=12, BI=3) + bnulr = BA.bclr(BO=4, BI=3) + + bltctr = BA.bcctr(BO=12, BI=0) + blectr = BA.bcctr(BO=4, BI=1) + beqctr = BA.bcctr(BO=12, BI=2) + bgectr = BA.bcctr(BO=4, BI=0) + bgtctr = BA.bcctr(BO=12, BI=1) + bnlctr = BA.bcctr(BO=4, BI=0) + bnectr = BA.bcctr(BO=4, BI=2) + bngctr = BA.bcctr(BO=4, BI=1) + bsoctr = BA.bcctr(BO=12, BI=3) + bnsctr = BA.bcctr(BO=4, BI=3) + bunctr = BA.bcctr(BO=12, BI=3) + bnuctr = BA.bcctr(BO=4, BI=3) + + bltlrl = BA.bclrl(BO=12, BI=0) + blelrl = BA.bclrl(BO=4, BI=1) + beqlrl = BA.bclrl(BO=12, BI=2) + bgelrl = BA.bclrl(BO=4, BI=0) + bgtlrl = BA.bclrl(BO=12, BI=1) + bnllrl = BA.bclrl(BO=4, BI=0) + bnelrl = BA.bclrl(BO=4, BI=2) + bnglrl = BA.bclrl(BO=4, BI=1) + bsolrl = BA.bclrl(BO=12, BI=3) + bnslrl = BA.bclrl(BO=4, BI=3) + bunlrl = BA.bclrl(BO=12, BI=3) + bnulrl = BA.bclrl(BO=4, BI=3) + + bltctrl = BA.bcctrl(BO=12, BI=0) + blectrl = BA.bcctrl(BO=4, BI=1) + beqctrl = BA.bcctrl(BO=12, BI=2) + bgectrl = BA.bcctrl(BO=4, BI=0) + bgtctrl = BA.bcctrl(BO=12, BI=1) + bnlctrl = BA.bcctrl(BO=4, BI=0) + bnectrl = BA.bcctrl(BO=4, BI=2) + bngctrl = BA.bcctrl(BO=4, BI=1) + bsoctrl = BA.bcctrl(BO=12, BI=3) + bnsctrl = BA.bcctrl(BO=4, BI=3) + bunctrl = BA.bcctrl(BO=12, BI=3) + bnuctrl = BA.bcctrl(BO=4, BI=3) + + # whew! and we haven't even begun the predicted versions... + + # F.6 Simplified Mnemonics for Condition Register + # Logical Instructions + + crset = BA.creqv(crbA="crbD", crbB="crbD") + crclr = BA.crxor(crbA="crbD", crbB="crbD") + cmove = BA.cror(crbA="crbB") + crnot = BA.crnor(crbA="crbB") + + # F.7 Simplified Mnemonics for Trap Instructions + + # these can wait! + + # F.8 Simplified Mnemonics for Special-Purpose + # Registers + + mfctr = BA.mfspr(spr=9) + mflr = BA.mfspr(spr=8) + mftbl = BA.mftb(spr=268) + mftbu = BA.mftb(spr=269) + mfxer = BA.mfspr(spr=1) + + mtctr = BA.mtspr(spr=9) + mtlr = BA.mtspr(spr=8) + mtxer = BA.mtspr(spr=1) + + + # F.9 Recommended Simplified Mnemonics + nop = BA.ori(rS=0, rA=0, UIMM=0) + + li = BA.addi(rA=0) + lis = BA.addis(rA=0) + + mr = BA.or_(rB="rS") + mrx = BA.or_x(rB="rS") + + not_ = BA.nor(rB="rS") + not_x = BA.norx(rB="rS") + + mtcr = BA.mtcrf(CRM=0xFF) + +def hi(w): + return w >> 16 + +def ha(w): + if (w >> 15) & 1: + return w >> 16 + 1 + else: + return w >> 16 + +def lo(w): + return w & 0x0000FFFF + +class MyPPCAssembler(PPCAssembler): + def load_word(self, rD, word): + self.addis(rD, r0, hi(word)) + self.ori(rD, rD, lo(word)) + def load_from(self, rD, addr): + self.addis(rD, r0, ha(addr)) + self.lwz(rD, rD, lo(addr)) + +def b(n): + r = [] + for i in range(32): + r.append(n&1) + n >>= 1 + r.reverse() + return ''.join(map(str, r)) + +from pypy.translator.asm.ppcgen.regname import * + +def main(): + + a = MyPPCAssembler() + + a.lwz(r5, r4, 12) + a.lwz(r6, r4, 16) + a.lwz(r7, r5, 8) + a.lwz(r8, r6, 8) + a.add(r3, r7, r8) + a.load_word(r4, lookup("PyInt_FromLong")) + a.mtctr(r4) + a.bctr() + + f = a.assemble(True) + print f(12,3) + + a = MyPPCAssembler() + a.label("loop") + a.mftbu(r3) + a.mftbl(r4) + a.mftbu(r5) + a.cmpw(r5, r3) + a.bne(-16) + a.load_word(r5, lookup("PyLong_FromUnsignedLongLong")) + a.mtctr(r5) + a.bctr() + + tb = a.assemble(True) + t0 = tb() + print [tb() - t0 for i in range(10)] + +if __name__ == '__main__': + main() Added: pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,91 @@ +from pypy.translator.asm.ppcgen.field import Field +from pypy.translator.asm.ppcgen import regname + +fields = { # bit margins are *inclusive*! (and bit 0 is + # most-significant, 31 least significant) + "opcode": ( 0, 5), + "AA": (30, 30), + "BD": (16, 29, 'signed'), + "BI": (11, 15), + "BO": ( 6, 10), + "crbA": (11, 15), + "crbB": (16, 20), + "crbD": ( 6, 10), + "crfD": ( 6, 8), + "crfS": (11, 13), + "CRM": (12, 19), + "d": (16, 31, 'signed'), + "FM": ( 7, 14), + "frA": (11, 15, 'unsigned', regname._F), + "frB": (16, 20, 'unsigned', regname._F), + "frC": (21, 25, 'unsigned', regname._F), + "frD": ( 6, 10, 'unsigned', regname._F), + "frS": ( 6, 10, 'unsigned', regname._F), + "IMM": (16, 19), + "L": (10, 10), + "LI": ( 6, 29, 'signed'), + "LK": (31, 31), + "MB": (21, 25), + "ME": (26, 30), + "NB": (16, 20), + "OE": (21, 21), + "rA": (11, 15, 'unsigned', regname._R), + "rB": (16, 20, 'unsigned', regname._R), + "Rc": (31, 31), + "rD": ( 6, 10, 'unsigned', regname._R), + "rS": ( 6, 10, 'unsigned', regname._R), + "SH": (16, 20), + "SIMM": (16, 31, 'signed'), + "SR": (12, 15), + "spr": (11, 20), + "TO": ( 6, 10), + "UIMM": (16, 31), + "XO1": (21, 30), + "XO2": (22, 30), + "XO3": (26, 30), +} + + +class IField(Field): + def __init__(self, name, left, right, signedness): + assert signedness == 'signed' + super(IField, self).__init__(name, left, right, signedness) + def encode(self, value): + # XXX should check range + value &= self.mask << 2 | 0x3 + return value & ~0x3 + def decode(self, inst): + mask = self.mask << 2 + v = inst & mask + if self.signed and (~mask >> 1) & mask & v: + return ~(~v&self.mask) + else: + return v + def r(self, i, labels, pc): + if not ppc_fields['AA'].decode(i): + v = self.decode(i) + if pc+v in labels: + return "%s (%r)"%(v, ', '.join(labels[pc+v])) + else: + return self.decode(i) + + +class spr(Field): + def encode(self, value): + value = (value&31) << 5 | (value >> 5 & 31) + return super(spr, self).encode(value) + def decode(self, inst): + value = super(spr, self).decode(inst) + return (value&31) << 5 | (value >> 5 & 31) + +# other special fields? + +ppc_fields = { + "LI": IField("LI", *fields["LI"]), + "BD": IField("BD", *fields["BD"]), + "spr": spr("spr", *fields["spr"]), +} + +for f in fields: + if f not in ppc_fields: + ppc_fields[f] = Field(f, *fields[f]) Added: pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,13 @@ +from pypy.translator.asm.ppcgen.form import Form +from pypy.translator.asm.ppcgen.ppc_field import ppc_fields + +class PPCForm(Form): + fieldmap = ppc_fields + + def __init__(self, *fnames): + super(PPCForm, self).__init__(*("opcode",) + fnames) + + def __call__(self, opcode, **specializations): + specializations['opcode'] = opcode + return super(PPCForm, self).__call__(**specializations) + Added: pypy/dist/pypy/translator/asm/ppcgen/pystructs.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/pystructs.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,22 @@ +class PyVarObject(object): + ob_size = 8 + +class PyObject(object): + ob_refcnt = 0 + ob_type = 4 + +class PyTupleObject(object): + ob_item = 12 + +class PyTypeObject(object): + tp_name = 12 + tp_basicsize = 16 + tp_itemsize = 20 + tp_dealloc = 24 + +class PyFloatObject(object): + ob_fval = 8 + +class PyIntObject(object): + ob_ival = 8 + Added: pypy/dist/pypy/translator/asm/ppcgen/regname.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/regname.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,18 @@ +class _R(int): + def __repr__(self): + return "r%s"%(super(_R, self).__repr__(),) + __str__ = __repr__ +class _F(int): + def __repr__(self): + return "fr%s"%(super(_F, self).__repr__(),) + __str__ = __repr__ + +r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, \ + r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, \ + r23, r24, r25, r26, r27, r28, r29, r30, r31 = map(_R, range(32)) + +fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7, fr8, fr9, fr10, fr11, fr12, \ + fr13, fr14, fr15, fr16, fr17, fr18, fr19, fr20, fr21, fr22, \ + fr23, fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31 = map(_F, range(32)) + +crf0, crf1, crf2, crf3, crf4, crf5, crf6, crf7 = range(8) Added: pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,11 @@ +import py + +_ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() + +try: + from _ppcgen import NSLookupAndBindSymbol + + def lookup(sym): + return NSLookupAndBindSymbol('_' + sym) +except ImportError: + from _ppcgen import dlsym as lookup Added: pypy/dist/pypy/translator/asm/ppcgen/test/__init__.py ============================================================================== Added: pypy/dist/pypy/translator/asm/ppcgen/test/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/test/autopath.py Mon Oct 10 19:49:28 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/translator/asm/ppcgen/test/test_field.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_field.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,65 @@ +import autopath + +from pypy.translator.asm.ppcgen.field import Field +from py.test import raises + +import random +import sys + +class TestFields(object): + def test_decode(self): + # this test is crappy + field = Field("test", 0, 31) + for i in range(100): + j = random.randrange(sys.maxint) + assert field.decode(j) == j + field = Field("test", 0, 31-4) + for i in range(100): + j = random.randrange(sys.maxint) + assert field.decode(j) == j>>4 + assert field.decode(j) == j>>4 + field = Field("test", 3, 31-4) + for i in range(100): + j = random.randrange(sys.maxint>>3) + assert field.decode(j) == j>>4 + + + def test_decode_unsigned(self): + field = Field("test", 16, 31) + for i in range(1000): + hi = long(random.randrange(0x10000)) << 16 + lo = long(random.randrange(0x10000)) + assert field.decode(hi|lo) == lo + + + def test_decode_signed(self): + field = Field("test", 16, 31, 'signed') + for i in range(1000): + hi = long(random.randrange(0x10000)) << 16 + lo = long(random.randrange(0x10000)) + word = hi|lo + if lo & 0x8000: + lo |= ~0xFFFF + assert field.decode(word) == lo + + + def test_error_checking_unsigned(self): + for b in range(0, 17): + field = Field("test", b, 15+b) + assert field.decode(field.encode(0)) == 0 + assert field.decode(field.encode(32768)) == 32768 + assert field.decode(field.encode(65535)) == 65535 + raises(ValueError, field.encode, -32768) + raises(ValueError, field.encode, -1) + raises(ValueError, field.encode, 65536) + + + def test_error_checking_signed(self): + for b in range(0, 17): + field = Field("test", b, 15+b, 'signed') + assert field.decode(field.encode(0)) == 0 + assert field.decode(field.encode(-32768)) == -32768 + assert field.decode(field.encode(32767)) == 32767 + raises(ValueError, field.encode, 32768) + raises(ValueError, field.encode, -32769) + Added: pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,69 @@ +import autopath +from pypy.translator.asm.ppcgen.ppc_assembler import b +import unittest +import random +import sys + +from pypy.translator.asm.ppcgen.form import Form, FormException +from pypy.translator.asm.ppcgen.field import Field +from pypy.translator.asm.ppcgen.assembler import Assembler + +# 0 31 +# +-------------------------------+ +# | h | l | +# +-------------------------------+ +# | hh | hl | lh | ll | +# +-------------------------------+ + +test_fieldmap = { + 'l' : Field('l', 16, 31), + 'h' : Field('h', 0, 15), + 'll': Field('ll', 24, 31), + 'lh': Field('lh', 16, 23), + 'hl': Field('hl', 8, 15), + 'hh': Field('hh', 0, 7), +} + +def p(w): + import struct + return struct.pack('i', w) + + +class TestForm(Form): + fieldmap = test_fieldmap + +class TestForms(object): + def test_bitclash(self): + raises(FormException, TestForm, 'h', 'hh') + raises(FormException, TestForm, + Field('t1', 0, 0), Field('t2', 0, 0)) + + def test_basic(self): + class T(Assembler): + i = TestForm('h', 'l')() + j = i(h=1) + k = i(l=3) + raises(FormException, k, l=0) + a = T() + a.i(5, 6) + assert p(a.assemble0()[0]) == '\000\005\000\006' + a = T() + a.j(2) + assert p(a.assemble0()[0]) == '\000\001\000\002' + a = T() + a.k(4) + assert p(a.assemble0()[0]) == '\000\004\000\003' + + def test_defdesc(self): + class T(Assembler): + i = TestForm('hh', 'hl', 'lh', 'll')() + i.default(hl=0).default(hh=1) + a = T() + a.i(1, 2, 3, 4) + assert p(a.assemble0()[0]) == '\001\002\003\004' + a = T() + a.i(1, 3, 4) + assert p(a.assemble0()[0]) == '\001\000\003\004' + a = T() + a.i(3, 4) + assert p(a.assemble0()[0]) == '\001\000\003\004' Added: pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,87 @@ +import unittest + +import random, sys, os + +from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler +from pypy.translator.asm.ppcgen.symbol_lookup import lookup +from pypy.translator.asm.ppcgen.func_builder import make_func +from pypy.translator.asm.ppcgen import form, func_builder +from pypy.translator.asm.ppcgen.regname import * + +class TestFuncBuilderTest(object): + def setup_class(cls): + if os.uname()[-1] != 'Power Macintosh': + py.test.skip("can't test all of ppcgen on non-PPC!") + + def test_simple(self): + a = MyPPCAssembler() + a.blr() + f = make_func(a, "O", "O") + assert f(1) == 1 + raises(TypeError, f) + raises(TypeError, f, 1, 2) + + def test_less_simple(self): + a = MyPPCAssembler() + s = lookup("PyNumber_Add") + a.load_word(r5, s) + a.mtctr(r5) + a.bctr() + f = make_func(a, "O", "OO") + raises(TypeError, f) + raises(TypeError, f, 1) + assert f(1, 2) == 3 + raises(TypeError, f, 1, 2, 3) + + def test_signature(self): + a = MyPPCAssembler() + a.add(r3, r3, r4) + a.blr() + f = make_func(a, "i", "ii") + raises(TypeError, f) + raises(TypeError, f, 1) + assert f(1, 2) == 3 + raises(TypeError, f, 1, 2, 3) + raises(TypeError, f, 1, "2") + + def test_signature2(self): + a = MyPPCAssembler() + a.add(r3, r3, r4) + a.add(r3, r3, r5) + a.add(r3, r3, r6) + a.add(r3, r3, r7) + s = lookup("PyInt_FromLong") + a.load_word(r0, s) + a.mtctr(r0) + a.bctr() + f = make_func(a, "O", "iiiii") + raises(TypeError, f) + raises(TypeError, f, 1) + assert f(1, 2, 3, 4, 5) == 1 + 2 + 3 + 4 + 5 + raises(TypeError, f, 1, 2, 3) + raises(TypeError, f, 1, "2", 3, 4, 5) + + def test_floats(self): + a = MyPPCAssembler() + a.fadd(fr1, fr1, fr2) + a.blr() + f = make_func(a, 'f', 'ff') + raises(TypeError, f) + raises(TypeError, f, 1.0) + assert f(1.0, 2.0) == 3.0 + raises(TypeError, f, 1.0, 2.0, 3.0) + raises(TypeError, f, 1.0, 2) + + def test_fast_entry(self): + a = MyPPCAssembler() + a.blr() + f = make_func(a, "O", "O") + assert f(1) == 1 + b = MyPPCAssembler() + from pypy.translator.asm.ppcgen import util + # eurgh!: + b.load_word(r0, util.access_at(id(f.code), 8) + f.FAST_ENTRY_LABEL) + b.mtctr(r0) + b.bctr() + g = make_func(b, "O", "O") + assert g(1) == 1 Added: pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,191 @@ +import random, sys, os + +from pypy.translator.asm.ppcgen.ppc_assembler import BasicPPCAssembler, MyPPCAssembler +from pypy.translator.asm.ppcgen.symbol_lookup import lookup +from pypy.translator.asm.ppcgen.regname import * +from pypy.translator.asm.ppcgen import form, pystructs + + +class TestDisassemble(object): + def test_match(self): + A = BasicPPCAssembler + a = A() + a.add(1, 2, 3) + inst = a.insts[-1] + assert A.add.match(inst.assemble()) + + +class TestAssemble(object): + + def setup_class(cls): + if os.uname()[-1] != 'Power Macintosh': + py.test.skip("can't test all of ppcgen on non-PPC!") + + def test_tuplelength(self): + a = MyPPCAssembler() + + a.lwz(3, 4, pystructs.PyVarObject.ob_size) + a.load_word(5, lookup("PyInt_FromLong")) + a.mtctr(5) + a.bctr() + + f = a.assemble() + assert f() == 0 + assert f(1) == 1 + assert f('') == 1 + + + def test_tuplelength2(self): + a = MyPPCAssembler() + + a.mflr(0) + a.stw(0, 1, 8) + a.stwu(1, 1, -80) + a.mr(3, 4) + a.load_word(5, lookup("PyTuple_Size")) + a.mtctr(5) + a.bctrl() + a.load_word(5, lookup("PyInt_FromLong")) + a.mtctr(5) + a.bctrl() + a.lwz(0, 1, 88) + a.addi(1, 1, 80) + a.mtlr(0) + a.blr() + + f = a.assemble() + assert f() == 0 + assert f(1) == 1 + assert f('') == 1 + assert f('', 3) == 2 + + + def test_intcheck(self): + a = MyPPCAssembler() + + a.lwz(r5, r4, pystructs.PyVarObject.ob_size) + a.cmpwi(r5, 1) + a.bne("not_one") + a.lwz(r5, r4, pystructs.PyTupleObject.ob_item + 0*4) + a.lwz(r5, r5, 4) + a.load_word(r6, lookup("PyInt_Type")) + a.cmpw(r5, r6) + a.bne("not_int") + a.li(r3, 1) + a.b("exit") + a.label("not_int") + a.li(r3, 0) + a.b("exit") + a.label("not_one") + a.li(r3, 2) + a.label("exit") + a.load_word(r5, lookup("PyInt_FromLong")) + a.mtctr(r5) + a.bctr() + + f = a.assemble() + + assert f() == 2 + assert f("", "") == 2 + assert f("") == 0 + assert f(1) == 1 + + + def test_raise(self): + a = MyPPCAssembler() + + a.mflr(0) + a.stw(0, 1, 8) + a.stwu(1, 1, -80) + + err_set = lookup("PyErr_SetObject") + exc = lookup("PyExc_ValueError") + + a.load_word(5, err_set) + a.mtctr(5) + a.load_from(3, exc) + a.mr(4, 3) + a.bctrl() + + a.li(3, 0) + + a.lwz(0, 1, 88) + a.addi(1, 1, 80) + a.mtlr(0) + a.blr() + + raises(ValueError, a.assemble()) + + + def test_makestring(self): + a = MyPPCAssembler() + + a.li(r3, 0) + a.li(r4, 0) + a.load_word(r5, lookup("PyString_FromStringAndSize")) + a.mtctr(r5) + a.bctr() + + f = a.assemble() + assert f() == '' + + + def test_numberadd(self): + a = MyPPCAssembler() + + a.lwz(r5, r4, pystructs.PyVarObject.ob_size) + a.cmpwi(r5, 2) + a.bne("err_out") + + a.lwz(r3, r4, 12) + a.lwz(r4, r4, 16) + + a.load_word(r5, lookup("PyNumber_Add")) + a.mtctr(r5) + a.bctr() + + a.label("err_out") + + a.mflr(r0) + a.stw(r0, r1, 8) + a.stwu(r1, r1, -80) + + err_set = lookup("PyErr_SetObject") + exc = lookup("PyExc_TypeError") + + a.load_word(r5, err_set) + a.mtctr(r5) + a.load_from(r3, exc) + a.mr(r4, r3) + a.bctrl() + + a.li(r3, 0) + + a.lwz(r0, r1, 88) + a.addi(r1, r1, 80) + a.mtlr(r0) + a.blr() + + f = a.assemble() + + raises(TypeError, f) + raises(TypeError, f, '', 1) + raises(TypeError, f, 1) + raises(TypeError, f, 1, 2, 3) + assert f(1, 2) == 3 + assert f('a', 'b') == 'ab' + + + def test_assemblerChecks(self): + def testFailure(idesc, *args): + a = MyPPCAssembler() + raises(ValueError, idesc.__get__(a), *args) + def testSucceed(idesc, *args): + a = MyPPCAssembler() + # "assertNotRaises" :-) + idesc.__get__(a)(*args) + testFailure(MyPPCAssembler.add, 32, 31, 30) + testFailure(MyPPCAssembler.add, -1, 31, 30) + testSucceed(MyPPCAssembler.bne, -12) + testSucceed(MyPPCAssembler.lwz, 0, 0, 32767) + testSucceed(MyPPCAssembler.lwz, 0, 0, -32768) Added: pypy/dist/pypy/translator/asm/ppcgen/util.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppcgen/util.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,23 @@ +from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler +from pypy.translator.asm.ppcgen.func_builder import make_func + +from regname import * + +def access_at(): + a = MyPPCAssembler() + + a.lwzx(r3, r3, r4) + a.blr() + + return make_func(a, "i", "ii") + +access_at = access_at() + +def itoO(): + a = MyPPCAssembler() + + a.blr() + + return make_func(a, "O", "i") + +itoO = itoO() Added: pypy/dist/pypy/translator/asm/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/test/__init__.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1 @@ +# ppc only for now!! Added: pypy/dist/pypy/translator/asm/test/autopath.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/test/autopath.py Mon Oct 10 19:49:28 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/translator/asm/test/test_asm.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Mon Oct 10 19:49:28 2005 @@ -0,0 +1,48 @@ +from pypy.translator.translator import Translator +import py +import os + +class TestAsm(object): + + def setup_class(cls): + if os.uname()[-1] != 'Power Macintosh': + py.test.skip('asm generation only on PPC') + cls.processor = 'ppc' + + def getcompiled(self, func, view=False): + t = Translator(func, simplifying=True) + # builds starting-types from func_defs + argstypelist = [] + if func.func_defaults is None: + assert func.func_code.co_argcount == 0 + argtypes = [] + else: + assert len(func.func_defaults) == func.func_code.co_argcount + argtypes = list(func.func_defaults) + a = t.annotate(argtypes) + a.simplify() + t.specialize() + t.checkgraphs() +# t.backend_optimizations() + if view: + t.view() + return t.asmcompile(self.processor) + + def dont_test_trivial(self): + def testfn(): + return None + f = self.getcompiled(testfn) + assert f() == None + + def test_int_add(self): + def testfn(x=int, y=int): + z = 1 + x + if z > 0: + return x + y + z + else: + return x + y - 42 + f = self.getcompiled(testfn)#, view=True) + assert f(2, 3) == testfn(2, 3) + assert f(-2, 3) == testfn(-2, 3) + + 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 Oct 10 19:49:28 2005 @@ -606,7 +606,7 @@ def process_MouseButtonDown(self, event): self.dragging = self.click_origin = event.pos self.click_time = time.time() - pygame.event.set_grab(True) +# pygame.event.set_grab(True) def process_MouseButtonUp(self, event): self.dragging = None Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Mon Oct 10 19:49:28 2005 @@ -327,6 +327,12 @@ self.frozen = True return genllvm.genllvm(self, really_compile=really_compile, standalone=standalone, optimize=optimize, exe_name=exe_name, gcpolicy=gcpolicy) + def asmcompile(self, processor='ppc'): + from pypy.translator.asm import genasm + assert processor == 'ppc', 'only ppc asm-generation supported for now' + assert self.rtyper is not None, 'must specialize' + return genasm.genasm(self) + def call(self, *args): """Calls underlying Python function.""" return self.entrypoint(*args) From mwh at codespeak.net Mon Oct 10 19:52:04 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 10 Oct 2005 19:52:04 +0200 (CEST) Subject: [pypy-svn] r18349 - in pypy/dist/pypy/translator: asm asm/ppcgen asm/ppcgen/test asm/test backendopt backendopt/test c/test goal Message-ID: <20051010175204.ABE8C27B56@code1.codespeak.net> Author: mwh Date: Mon Oct 10 19:51:50 2005 New Revision: 18349 Modified: pypy/dist/pypy/translator/asm/ (props changed) pypy/dist/pypy/translator/asm/__init__.py (props changed) pypy/dist/pypy/translator/asm/autopath.py (props changed) pypy/dist/pypy/translator/asm/genasm.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/ (props changed) pypy/dist/pypy/translator/asm/ppcgen/__init__.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/assembler.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/autopath.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/field.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/form.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/func_builder.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/ppc_field.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/ppc_form.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/pystructs.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/regname.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/test/ (props changed) pypy/dist/pypy/translator/asm/ppcgen/test/__init__.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/test/autopath.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/test/test_field.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py (props changed) pypy/dist/pypy/translator/asm/ppcgen/util.py (props changed) pypy/dist/pypy/translator/asm/test/ (props changed) pypy/dist/pypy/translator/asm/test/__init__.py (props changed) pypy/dist/pypy/translator/asm/test/autopath.py (props changed) pypy/dist/pypy/translator/asm/test/test_asm.py (props changed) pypy/dist/pypy/translator/backendopt/propagate.py (props changed) pypy/dist/pypy/translator/backendopt/tailrecursion.py (props changed) pypy/dist/pypy/translator/backendopt/test/test_propagate.py (props changed) pypy/dist/pypy/translator/backendopt/test/test_tailrecursion.py (props changed) pypy/dist/pypy/translator/c/test/test_lladdresses.py (props changed) pypy/dist/pypy/translator/goal/bench-cronjob.py (props changed) Log: FIXEOL From ericvrp at codespeak.net Mon Oct 10 22:03:04 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 10 Oct 2005 22:03:04 +0200 (CEST) Subject: [pypy-svn] r18350 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051010200304.5393027B74@code1.codespeak.net> Author: ericvrp Date: Mon Oct 10 22:03:02 2005 New Revision: 18350 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/exception.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/gc.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/test/test_lltype.py pypy/dist/pypy/translator/js/varsize.py Log: Intermediate commit, need checkpoint. Working on arrays. Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Mon Oct 10 22:03:02 2005 @@ -43,7 +43,7 @@ # def writedatatypedecl(self, codewriter): codewriter.arraydef(self.ref, - self.db.get_machine_word(), + 'int', self.db.repr_type(self.arraytype)) def writedecl(self, codewriter): @@ -67,7 +67,7 @@ self.ref = "arraytype_Void" def writedatatypedecl(self, codewriter): - td = "%s = type { %s }" % (self.ref, self.db.get_machine_word()) + td = "%s = type { int }" % self.ref codewriter.append(td) class ArrayNode(ConstantLLVMNode): @@ -83,7 +83,7 @@ self.db = db self.value = value self.arraytype = lltype.typeOf(value).OF - prefix = '%arrayinstance' + prefix = 'arrayinstance' name = '' #str(value).split()[1] self.ref = self.make_ref(prefix, name) @@ -113,18 +113,15 @@ def get_typerepr(self): arraylen = self.get_arrayvalue()[0] typeval = self.db.repr_type(self.arraytype) - return "{ %s, [%s x %s] }" % (self.db.get_machine_word(), - arraylen, typeval) + return "{ int, [%s x %s] }" % (arraylen, typeval) def get_ref(self): - typeval = self.db.repr_type(lltype.typeOf(self.value)) - ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), - self.ref, - typeval) - + #typeval = self.db.repr_type(lltype.typeOf(self.value)) + #ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), self.ref, typeval) p, c = lltype.parentlink(self.value) assert p is None, "child arrays are NOT needed by rtyper" - return ref + #return ref + return self.ref def get_pbcref(self, toptr): ref = self.ref @@ -146,11 +143,14 @@ 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(), - self.get_length(), - physicallen, - typeval, - arrayrepr) + value = "[%s, %s]" % (self.get_length(), arrayrepr) + return value + + # first length is logical, second is physical + value = "int %s, [%s x %s] %s" % (self.get_length(), + physicallen, + typeval, + arrayrepr) s = "%s {%s}" % (self.get_typerepr(), value) return s @@ -186,11 +186,9 @@ assert isinstance(lltype.typeOf(value), lltype.Array) self.db = db self.value = value - prefix = '%arrayinstance' + prefix = 'arrayinstance' name = '' #str(value).split()[1] self.ref = self.make_ref(prefix, name) def constantvalue(self): - return "{ %s } {%s %s}" % (self.db.get_machine_word(), - self.db.get_machine_word(), - len(self.value.items)) + return "{ int } {int %s}" % len(self.value.items) Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Mon Oct 10 22:03:02 2005 @@ -33,20 +33,25 @@ openblock = label def closeblock(self): - self.append('break') + self.append('continue') - def globalinstance(self, name, typeandata): - self.llvm("%s = %s global %s" % (name, "internal", typeandata)) + def globalinstance(self, name, typeanddata): + #self.append('%s = %s' % (name, typeanddata[1:].split('{')[1][:-1]), 0) + lines = typeanddata.split('\n') + #self.llvm("%s = global %s" % (name, lines[0]), 0) + self.append("%s = %s" % (name, lines[0]), 0) + for line in lines[1:]: + self.llvm(line, 0) def structdef(self, name, typereprs): - self.llvm("%s = type { %s }" %(name, ", ".join(typereprs))) + self.llvm("%s = type { %s }" %(name, ", ".join(typereprs)), 0) def arraydef(self, name, lentype, typerepr): - self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr)) + self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr), 0) def funcdef(self, name, rettyperepr, argtypereprs): self.llvm("%s = type %s (%s)" % (name, rettyperepr, - ", ".join(argtypereprs))) + ", ".join(argtypereprs)), 0) def declare(self, decl): #self.llvm("declare %s" % decl, 0) @@ -139,20 +144,25 @@ self.llvm("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) def call(self, targetvar, returntype, functionref, argrefs, argtypes, label=None, except_label=None): - args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) + #args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) + args = ", ".join(argrefs) if except_label: self.js.exceptionpolicy.invoke(self, targetvar, returntype, functionref, args, label, except_label) else: if returntype == 'void': - self.llvm("call void %s(%s)" % (functionref, args)) + #self.llvm("call void %s(%s)" % (functionref, args)) + self.append('%s(%s)' % (functionref, args)) else: - self.llvm("%s = call %s %s(%s)" % (targetvar, returntype, functionref, args)) + #self.llvm("%s = call %s %s(%s)" % (targetvar, returntype, functionref, args)) + self.append('%s = %s(%s)' % (targetvar, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): + self.comment('codewriter cast 1 targettype=%(targettype)s, targetvar=%(targetvar)s, fromtype=%(fromtype)s, fromvar=%(fromvar)s' % locals()) if fromtype == 'void' and targettype == 'void': return + self.comment('codewriter cast 2') if targettype == fromtype: - self.append("%(targetvar)s = %(fromvar)s%(convfunc)s" % locals()) + self.append("%(targetvar)s = %(fromvar)s" % locals()) elif targettype in ('int','uint',): self.append("%(targetvar)s = Math.floor(%(fromvar)s)" % locals()) elif targettype in ('double',): @@ -170,16 +180,30 @@ res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, word 0, " % locals() res += ", ".join(["%s %s" % (t, i) for t, i in indices]) self.llvm(res) - - def load(self, targetvar, targettype, ptr): - self.llvm("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) - - def store(self, valuetype, valuevar, ptr): - self.llvm("store %(valuetype)s %(valuevar)s, " - "%(valuetype)s* %(ptr)s" % locals()) + + #res = "%(targetvar)s = %(typevar)s" % locals() + #res += ''.join(['[%s]' % i for t, i in indices]) + #self.append(res) + + #def load(self, targetvar, targettype, ptr): + # self.llvm("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) + + def load(self, destvar, src, srcindices): + res = "%(destvar)s = %(src)s" % locals() + res += ''.join(['[%s]' % index for index in srcindices]) + self.append(res) + + #def store(self, valuetype, valuevar, ptr): + # self.llvm("store %(valuetype)s %(valuevar)s, %(valuetype)s* %(ptr)s" % locals()) + + def store(self, dest, destindices, srcvar): + res = dest + res += ''.join(['[%s]' % index for index in destindices]) + res += " = %(srcvar)s" % locals() + self.append(res) def debugcomment(self, tempname, len, tmpname): - res = "%s = call ccc %(word)s (sbyte*, ...)* printf(" % locals() + res = "%s = call %(word)s (sbyte*, ...)* printf(" % locals() res += "sbyte* getelementptr ([%s x sbyte]* %s, word 0, word 0) )" % locals() res = res % (tmpname, len, tmpname) self.llvm(res) Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Mon Oct 10 22:03:02 2005 @@ -16,6 +16,16 @@ log = log.database class Database(object): + + primitives = { + lltype.Char: "sbyte", + lltype.Bool: "bool", + lltype.Float: "double", + lltype.Signed: "int", + lltype.Unsigned: "uint", + lltype.UniChar: "uint", + lltype.Void: "void"} + def __init__(self, genllvm, translator): self.genllvm = genllvm self.translator = translator @@ -26,33 +36,6 @@ # 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): @@ -347,12 +330,6 @@ 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] - # __________________________________________________________ # Other helpers Modified: pypy/dist/pypy/translator/js/exception.py ============================================================================== --- pypy/dist/pypy/translator/js/exception.py (original) +++ pypy/dist/pypy/translator/js/exception.py Mon Oct 10 22:03:02 2005 @@ -3,7 +3,7 @@ RINGBUFFER_ENTRY_MAXSIZE = 16 RINGBUGGER_OVERSIZE = RINGBUGGER_SIZE + RINGBUFFER_ENTRY_MAXSIZE RINGBUFFER_LLVMCODE = ''' -internal fastcc sbyte* %%malloc_exception(uint %%nbytes) { +sbyte* %%malloc_exception(uint %%nbytes) { %%cond = setle uint %%nbytes, %d br bool %%cond, label %%then, label %%else @@ -16,7 +16,7 @@ ret sbyte* %%tmp.4 else: - %%tmp.8 = call ccc sbyte* %%GC_malloc(uint %%nbytes) + %%tmp.8 = call sbyte* %%GC_malloc(uint %%nbytes) ret sbyte* %%tmp.8 } ''' % (RINGBUFFER_ENTRY_MAXSIZE, RINGBUGGER_OVERSIZE, RINGBUGGER_SIZE-1) @@ -46,7 +46,7 @@ return noresult def new(exceptionpolicy=None): #factory - exceptionpolicy = exceptionpolicy or 'explicit' + exceptionpolicy = exceptionpolicy or 'invokeunwind' if exceptionpolicy == 'invokeunwind': from pypy.translator.js.exception import InvokeUnwindExceptionPolicy exceptionpolicy = InvokeUnwindExceptionPolicy() @@ -75,7 +75,7 @@ returntype, entrypointname = entrynode.getdecl().split('%', 1) noresult = self._noresult(returntype) return ''' -ccc %(returntype)s%%__entrypoint__%(entrypointname)s { +%(returntype)s%%__entrypoint__%(entrypointname)s { %%result = invoke %(returntype)s%%%(entrypointname)s to label %%no_exception except label %%exception no_exception: @@ -86,13 +86,13 @@ ret %(noresult)s } -ccc int %%__entrypoint__raised_LLVMException() { +int %%__entrypoint__raised_LLVMException() { %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type %%result = cast %%RPYTHON_EXCEPTION_VTABLE* %%tmp to int ret int %%result } -internal fastcc void %%unwind() { +void %%unwind() { unwind } ''' % locals() + self.RINGBUFFER_LLVMCODE @@ -164,7 +164,7 @@ returntype, entrypointname = entrynode.getdecl().split('%', 1) noresult = self._noresult(returntype) return ''' -ccc %(returntype)s%%__entrypoint__%(entrypointname)s { +%(returntype)s%%__entrypoint__%(entrypointname)s { store %%RPYTHON_EXCEPTION_VTABLE* null, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type %%result = call %(returntype)s%%%(entrypointname)s %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type @@ -178,13 +178,13 @@ ret %(noresult)s } -ccc int %%__entrypoint__raised_LLVMException() { +int %%__entrypoint__raised_LLVMException() { %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type %%result = cast %%RPYTHON_EXCEPTION_VTABLE* %%tmp to int ret int %%result } -internal fastcc void %%unwind() { +void %%unwind() { ret void } ''' % locals() + self.RINGBUFFER_LLVMCODE Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Mon Oct 10 22:03:02 2005 @@ -12,21 +12,25 @@ log = log.funcnode class FuncTypeNode(LLVMNode): + #def __init__(self, db, type_): + # #XXX not sure if we need FuncTypeNode with Javascript + # pass + __slots__ = "db type_ ref".split() - + def __init__(self, db, type_): self.db = db assert isinstance(type_, lltype.FuncType) self.type_ = type_ self.ref = self.make_ref('%functiontype', '') - + def __str__(self): return "" % self.ref - + def setup(self): self.db.prepare_type(self.type_.RESULT) self.db.prepare_type_multi(self.type_._trueargs()) - + def writedatatypedecl(self, codewriter): returntype = self.db.repr_type(self.type_.RESULT) inputargtypes = [self.db.repr_type(a) for a in self.type_._trueargs()] Modified: pypy/dist/pypy/translator/js/gc.py ============================================================================== --- pypy/dist/pypy/translator/js/gc.py (original) +++ pypy/dist/pypy/translator/js/gc.py Mon Oct 10 22:03:02 2005 @@ -56,8 +56,8 @@ def declarations(self): return ''' -declare ccc sbyte* %GC_malloc(uint) -declare ccc sbyte* %GC_malloc_atomic(uint) +declare sbyte* %GC_malloc(uint) +declare sbyte* %GC_malloc_atomic(uint) %GC_all_interior_pointers = external global int ''' @@ -69,12 +69,12 @@ t = ''' %%malloc.Size%(cnt)s = getelementptr %(type_)s* null, %(uword)s %(s)s %%malloc.SizeU%(cnt)s = cast %(type_)s* %%malloc.Size%(cnt)s to %(uword)s -%%malloc.Ptr%(cnt)s = call ccc sbyte* %%GC_malloc%(atomic)s(%(uword)s %%malloc.SizeU%(cnt)s) +%%malloc.Ptr%(cnt)s = call sbyte* %%GC_malloc%(atomic)s(%(uword)s %%malloc.SizeU%(cnt)s) %(targetvar)s = cast sbyte* %%malloc.Ptr%(cnt)s to %(type_)s* ''' % locals() if is_atomic: t += ''' -call ccc void %%llvm.memset(sbyte* %%malloc.Ptr%(cnt)s, ubyte 0, uint %%malloc.SizeU%(cnt)s, uint 0) +call void %%llvm.memset(sbyte* %%malloc.Ptr%(cnt)s, ubyte 0, uint %%malloc.SizeU%(cnt)s, uint 0) ''' % locals() return t Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Mon Oct 10 22:03:02 2005 @@ -224,6 +224,7 @@ 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]) + self.codewriter.comment(op.opname) self.codewriter.cast(targetvar, fromtype, fromvar, targettype) same_as = cast_primitive @@ -444,8 +445,6 @@ 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) @@ -456,13 +455,14 @@ array, arraytype = self.db.repr_argwithtype(op.args[0]) index = self.db.repr_arg(op.args[1]) indextype = self.db.repr_arg_type(op.args[1]) - tmpvar = self.db.repr_tmpvar() targetvar = self.db.repr_arg(op.result) targettype = self.db.repr_arg_type(op.result) if targettype != "void": - self.codewriter.getelementptr(tmpvar, arraytype, array, - ("uint", 1), (indextype, index)) - self.codewriter.load(targetvar, targettype, tmpvar) + #tmpvar = self.db.repr_tmpvar() + #self.codewriter.getelementptr(tmpvar, arraytype, array, + # ("uint", 1), (indextype, index)) + #self.codewriter.load(targetvar, targettype, tmpvar) + self.codewriter.load(targetvar, array, (1, index)) else: self._skipped(op) @@ -478,15 +478,14 @@ array, arraytype = self.db.repr_argwithtype(op.args[0]) index = self.db.repr_arg(op.args[1]) indextype = self.db.repr_arg_type(op.args[1]) - - tmpvar = self.db.repr_tmpvar() - valuevar = self.db.repr_arg(op.args[2]) valuetype = self.db.repr_arg_type(op.args[2]) if valuetype != "void": - self.codewriter.getelementptr(tmpvar, arraytype, array, - ("uint", 1), (indextype, index)) - self.codewriter.store(valuetype, valuevar, tmpvar) + #tmpvar = self.db.repr_tmpvar() + #self.codewriter.getelementptr(tmpvar, arraytype, array, + # ("uint", 1), (indextype, index)) + #self.codewriter.store(valuetype, valuevar, tmpvar) + self.codewriter.store(array, (1, index), valuevar) else: self._skipped(op) Modified: pypy/dist/pypy/translator/js/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/js/test/test_lltype.py Mon Oct 10 22:03:02 2005 @@ -127,7 +127,7 @@ assert f(2) == 0 assert f(3) == 17 -def test_array_constant(): +def test_array_constant1(): A = lltype.GcArray(lltype.Signed) a = lltype.malloc(A, 3) a[0] = 100 Modified: pypy/dist/pypy/translator/js/varsize.py ============================================================================== --- pypy/dist/pypy/translator/js/varsize.py (original) +++ pypy/dist/pypy/translator/js/varsize.py Mon Oct 10 22:03:02 2005 @@ -3,7 +3,7 @@ def write_constructor(db, codewriter, ref, constructor_decl, ARRAY, indices_to_array=()): - codewriter.comment('TODO: ' + constructor_decl) + codewriter.comment('TODO: ' + constructor_decl, 0) return #varsized arrays and structs look like this: From ericvrp at codespeak.net Mon Oct 10 22:15:38 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Mon, 10 Oct 2005 22:15:38 +0200 (CEST) Subject: [pypy-svn] r18351 - pypy/dist/pypy/translator/js Message-ID: <20051010201538.1C53927B74@code1.codespeak.net> Author: ericvrp Date: Mon Oct 10 22:15:37 2005 New Revision: 18351 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py Log: Simplifying arraydefinitions. Stripping of the initial length field that got added by the llvm backend. Javascript can give us this information in case we even need it. Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Mon Oct 10 22:15:37 2005 @@ -107,7 +107,8 @@ def get_arrayvalue(self): items = self.value.items l = len(items) - r = "[%s]" % ", ".join([self.db.repr_constant(v)[1] for v in items]) + #r = "[%s]" % ", ".join([self.db.repr_constant(v)[1] for v in items]) + r = "[%s]" % ", ".join([str(v) for v in items]) return l, r def get_typerepr(self): @@ -140,20 +141,17 @@ def constantvalue(self): physicallen, arrayrepr = self.get_arrayvalue() - typeval = self.db.repr_type(self.arraytype) - - # first length is logical, second is physical - value = "[%s, %s]" % (self.get_length(), arrayrepr) - return value - - # first length is logical, second is physical - value = "int %s, [%s x %s] %s" % (self.get_length(), - physicallen, - typeval, - arrayrepr) + return arrayrepr - s = "%s {%s}" % (self.get_typerepr(), value) - return s + ## first length is logical, second is physical + #typeval = self.db.repr_type(self.arraytype) + #value = "int %s, [%s x %s] %s" % (self.get_length(), + # physicallen, + # typeval, + # arrayrepr) + # + #s = "%s {%s}" % (self.get_typerepr(), value) + #return s class StrArrayNode(ArrayNode): __slots__ = "".split() Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Mon Oct 10 22:15:37 2005 @@ -462,7 +462,7 @@ #self.codewriter.getelementptr(tmpvar, arraytype, array, # ("uint", 1), (indextype, index)) #self.codewriter.load(targetvar, targettype, tmpvar) - self.codewriter.load(targetvar, array, (1, index)) + self.codewriter.load(targetvar, array, (index,)) else: self._skipped(op) @@ -485,7 +485,7 @@ #self.codewriter.getelementptr(tmpvar, arraytype, array, # ("uint", 1), (indextype, index)) #self.codewriter.store(valuetype, valuevar, tmpvar) - self.codewriter.store(array, (1, index), valuevar) + self.codewriter.store(array, (index,), valuevar) else: self._skipped(op) Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Mon Oct 10 22:15:37 2005 @@ -44,10 +44,9 @@ super(StructVarsizeTypeNode, self).__init__(db, struct) prefix = '%new.varsizestruct.' self.constructor_ref = self.make_ref(prefix, self.name) - self.constructor_decl = "%s * %s(%s %%len)" % \ + self.constructor_decl = "%s * %s(int %%len)" % \ (self.ref, - self.constructor_ref, - self.db.get_machine_word()) + self.constructor_ref) def __str__(self): return "" %(self.ref,) From boria at codespeak.net Tue Oct 11 10:15:14 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Tue, 11 Oct 2005 10:15:14 +0200 (CEST) Subject: [pypy-svn] r18362 - in pypy/dist/pypy/rpython/ootype: . test Message-ID: <20051011081514.8314E27B5E@code1.codespeak.net> Author: boria Date: Tue Oct 11 10:15:14 2005 New Revision: 18362 Modified: pypy/dist/pypy/rpython/ootype/ootype.py pypy/dist/pypy/rpython/ootype/test/test_ootype.py Log: * Check that default field values are correctly typed in Class.__init__() Modified: pypy/dist/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/ootype.py Tue Oct 11 10:15:14 2005 @@ -137,6 +137,11 @@ for name, defn in fields.iteritems(): if type(defn) is not tuple: fields[name] = (defn, defn._defl()) + else: + ootype, default = defn + + if ootype != typeOf(default): + raise TypeError("Expected type %r for default" % ootype) # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 10:15:14 2005 @@ -21,3 +21,5 @@ c = new(C) assert c.a == 3 + + py.test.raises(TypeError, "Class('test', None, {'a': (Signed, 3.0)})") From arigo at codespeak.net Tue Oct 11 10:28:09 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 10:28:09 +0200 (CEST) Subject: [pypy-svn] r18363 - pypy/dist/pypy/doc Message-ID: <20051011082809.B8BD427B5E@code1.codespeak.net> Author: arigo Date: Tue Oct 11 10:28:05 2005 New Revision: 18363 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Talk about classes and instances and pbcs. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Tue Oct 11 10:28:05 2005 @@ -662,9 +662,9 @@ * List(*v*) -- list; *v* is a variable summarizing the items of the list (there is one such term per variable); -* Callable(*set*) -- where the *set* is a subset of the (finite) set of - all functions, all classes, and all pairs of a class and a function - (written ``class.f``). +* Pbc(*set*) -- where the *set* is a subset of the (finite) set of all + `Prebuilt Constants`_, defined below. This set includes all the + callables of the user program: functions, classes, and methods. * None -- stands for the singleton ``None`` object of Python. @@ -673,8 +673,8 @@ which stands for "either the object described or ``None``". We use it to propagate knowledge about which variable, after translation to C, could ever contain a NULL pointer. (More precisely, there are a -NullableStr, nullable instances, and nulllable callables, and all lists -are implicitely assumed to be nullable). +NullableStr, nullable instances, and nullable Pbcs, and all lists are +implicitely assumed to be nullable). Each annotation corresponds to a family of run-time Python object; the ordering of the lattice is essentially the subset order. Formally, it @@ -688,7 +688,7 @@ * Inst(*subclass*) <= Inst(*class*) -- for any class and subclass; -* Callable(*subset*) <= Callable(*set*); +* Pbc(*subset*) <= Pbc(*set*); * a <= b -- for any annotation *a* with a nullable twin *b*; @@ -706,8 +706,8 @@ / NullableStr | | | Int / \ | (lists) | / Str \ (instances) | | - NonNegInt \ \ | | (callables) - \ Char \ |\ / / + NonNegInt \ \ | | (Pbcs) + \ Char \ |\ / / Bool \ \ | \ / / \ \ `----- None -----/ \ \ | / / @@ -752,9 +752,9 @@ \ \ \ / / / '------------'--- None ----'------------' -The callables form a classical finite set-of-subsets lattice. In -practice, we consider ``None`` as a degenerated callable, so the None -annotation is actually Callable({None}). +The Pbcs form a classical finite set-of-subsets lattice. In practice, +we consider ``None`` as a degenerated prebuilt constant, so the None +annotation is actually Pbc({None}). We should mention (but ignore for the sequel) that all annotations also have a variant where they stand for a single known object; this @@ -1002,6 +1002,59 @@ As with `merge_into`_, it identifies the two lists. +Prebuilt constants +~~~~~~~~~~~~~~~~~~ + +The ``Pbc`` annotations play a special role in our approach. They +regroup in a single family most of the constant user-defined objects +that pre-exist the annotation phase. This includes the functions and +classes defined in the user program, but also some other objects that +have been built while the user program was initializing itself. + +The presence of the latter kind of objects -- which comes with a number +of new problems to solve -- is a distinguishing property of the idea of +analysing a live program instead of static source code. All the user +objects that pre-exist the annotation phase are divided in two further +families: the "frozen prebuilt constants" ones and the "prebuilt +instances". By default, instances of some user-defined class that +happens to pre-exist annotation have no constantness requirement on +their own; after annotation and possibly compilation, these instances +will continue to behave as regular mutable instances of that class. +These prebuilt instances are decribed in another section (`Constant +annotations`_). However, the user program can give a hint that forces +the annotator to consider the object as a "frozen prebuilt constant". +The object is then considered as a now-immutable container of +attributes. It looses its object-oriented aspects and its class becomes +irrelevant -- it was only useful to the user program to build the object +up to its current state. + +In summary, the prebuilt constants are: + +* all functions ``f`` of the user program (including the ones appearing + as methods); + +* all classes ``C`` of the user program; + +* all frozen prebuilt constants; + +For convenience, we add the following objects to the above set: + +* for each function ``f`` and class ``C``, a "potential bound method" + object written ``C.f``, used below to handle method calls; + +* the singleton None object (a special case of frozen prebuilt constant). + +The annotation ``Pbc(*set*)`` stands for an object that belongs to the +specified *set* of prebuilt constant objects, which is a subset of all +the prebuilt constant objects. + +In practice, the set of all prebuilt constants is not fixed in advance, +but grows while annotation discovers new functions and classes and +frozen user objects; only the objects that are still alive will be +included in the set, leaving out the ones that were only relevant during +the initialization phase of the program. + + Classes and instances ~~~~~~~~~~~~~~~~~~~~~ @@ -1038,7 +1091,7 @@ program point are instances of a user-defined common base class, i.e. not ``object``. -We recall from `definition of V`_ that we have a variable ``v_C.attr`` +Remember from `definition of V`_ that we have a variable ``v_C.attr`` for each class ``C`` and each possible attribute name ``attr``. The annotation state *(b,E)* has the following meaning on these variables: @@ -1068,12 +1121,37 @@ E' = E union (v_C.attr ~ v_D.attr) for all D subclass of C merge_into(z, v_C.attr) -Note the similarity with the lists' ``getitem`` and ``setitem``, in +The purpose of ``lookup_filter`` is to avoid loosing precision in method +calls. Indeed, as described more precisely in `Constant annotations`_ +below, if ``attr`` names a method of the class ``C`` then the binding +``b(v_C.attr)`` is a ``Pbc`` that includes all the "potental bound +method" objects ``D.f``, for each subclass ``D`` of ``C`` where a +function ``f`` is present under the name ``attr``. + +XXX + + +if ``attr`` is a method defined on XXX:: + + lookup_filter(Pbc(set), class) = Pbc(newset) where + we only keep in newset the non-methods, and the following methods: + * the ones bound to a strict subclass of 'class', and + * among the methods bound the 'class' or superclasses, only the + one from the most derived class. + lookup_filter(NonPbcAnnotation, class) = NonPbcAnnotation + +Note the similarity with the ``getitem`` and ``setitem`` of lists, in particular the usage of the auxiliary variable *z'*. XXX +Constant annotations +~~~~~~~~~~~~~~~~~~~~ + +XXX constant arguments to operations + + Draft ~~~~~ @@ -1159,13 +1237,6 @@ lookup_filter(NonPbcAnnotation, class) = NonPbcAnnotation -Prebuilt constants -~~~~~~~~~~~~~~~~~~ - -XXX - -XXX constant arguments to operations - Termination ~~~~~~~~~~~ @@ -1173,12 +1244,12 @@ The lattice is finite, although its size depends on the size of the -program. The List part has the same size as *V*, and the Callable part -is exponential on the number of callables. However, in this model a -chain of annotations (where each one is larger than the previous) cannot -be longer than:: +program. The List part has the same size as *V*, and the Pbc part is +exponential on the number of prebuilt constants. However, in this model +a chain of annotations (where each one is larger than the previous) +cannot be longer than:: - max(5, number-of-callables + 3, depth-of-class-hierarchy + 3). + max(5, number-of-pbcs + 3, depth-of-class-hierarchy + 3). In the extended lattice used in practice it is more difficult to compute an upper bound. Such a bound exists -- some considerations can even From mwh at codespeak.net Tue Oct 11 10:38:37 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 10:38:37 +0200 (CEST) Subject: [pypy-svn] r18366 - in pypy/dist/pypy/translator/asm: . i386gen test Message-ID: <20051011083837.C4E1927B75@code1.codespeak.net> Author: mwh Date: Tue Oct 11 10:38:30 2005 New Revision: 18366 Added: pypy/dist/pypy/translator/asm/i386gen/ pypy/dist/pypy/translator/asm/i386gen/__init__.py pypy/dist/pypy/translator/asm/i386gen/i386_assembler.py Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: Made PPC assembly generation test skip cleanly on windows. Added stub-only for i386 pass. No code yet generated. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 11 10:38:30 2005 @@ -1,11 +1,30 @@ +import sys from pypy.objspace.flow.model import traverse, Block, Variable, Constant -from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler -from pypy.translator.asm.ppcgen.func_builder import make_func + + +#Available Machine code targets (processor+operating system) +TARGET_PPC=1 +TARGET_WIN386=2 + +#set one of these +ASM_TARGET=TARGET_PPC +#ASM_TARGET=TARGET_WIN386 + + +if ASM_TARGET==TARGET_PPC: + from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler + from pypy.translator.asm.ppcgen.func_builder import make_func +elif ASM_TARGET==TARGET_WIN386: + from pypy.translator.asm.i386gen.i386_assembler import i386Assembler as PPCAssembler #spoof system for time being + from pypy.translator.asm.i386gen.i386_assembler import make_func +else: + raise Exception,'Unknown Machine-code target specified. Set ASM_TARGET=TARGET_XXXX ' + def genlinkcode(link): for s, t in zip(link.args, link.target.inputargs): print ' ', 'mr', t, s - + def genasm(translator): @@ -15,8 +34,10 @@ g = FuncGenerator(graph) g.gencode() + if ASM_TARGET==TARGET_WIN386: + g.assembler.dump() return make_func(g.assembler, 'i', 'ii') - + class FuncGenerator(object): @@ -33,9 +54,13 @@ self.next_register = 3 for var in graph.startblock.inputargs: self.assign_register(var) + self._block_counter = 0 self.assembler = PPCAssembler() + + + def assign_register(self, var): assert var not in self._var2reg self._var2reg[var] = self.next_register @@ -116,4 +141,4 @@ def same_as(self, dest, v1): self.assembler.mr(self.reg(dest), self.reg(v1)) - + Added: pypy/dist/pypy/translator/asm/i386gen/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/i386gen/__init__.py Tue Oct 11 10:38:30 2005 @@ -0,0 +1 @@ +#thats all Added: pypy/dist/pypy/translator/asm/i386gen/i386_assembler.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/i386gen/i386_assembler.py Tue Oct 11 10:38:30 2005 @@ -0,0 +1,44 @@ +"""i386 Basic assembler... +Designed to mirror the PPC assembler system, operands added as required. + +Current system needs to assemble given, code, link into python, and return python +callabale. (Stub routine currently given). + +""" + +class i386Assembler: + + def __init__(self): + self._opcodes=[] + + def __getattr__(self,attr): + def func(*args): + return self.op(attr,args) + return func + + def op(self,opcode,*args): + self._opcodes.append((opcode,args)) + + def Make_func(cls,assembler,input='ii',output='i'): + return lambda x,y:x+y+1 + + Make_func=classmethod(Make_func) + + def dump(self): + l=1000 + for op in self._opcodes: + print '>>%d :%s' %(l,str(op)) + l+=1 + +make_func=i386Assembler.Make_func + + +if __name__=='__main__': + a=i386Assembler() + a.op('mov','ax,''bx') + + a.mov('spi','esi') + print a._opcodes + a.dump() + + Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Tue Oct 11 10:38:30 2005 @@ -3,15 +3,16 @@ import os class TestAsm(object): - + def setup_class(cls): - if os.uname()[-1] != 'Power Macintosh': + if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': py.test.skip('asm generation only on PPC') + cls.processor = 'ppc' - + def getcompiled(self, func, view=False): t = Translator(func, simplifying=True) - # builds starting-types from func_defs + # builds starting-types from func_defs argstypelist = [] if func.func_defaults is None: assert func.func_code.co_argcount == 0 @@ -33,7 +34,7 @@ return None f = self.getcompiled(testfn) assert f() == None - + def test_int_add(self): def testfn(x=int, y=int): z = 1 + x @@ -42,7 +43,8 @@ else: return x + y - 42 f = self.getcompiled(testfn)#, view=True) + assert f(2, 3) == testfn(2, 3) assert f(-2, 3) == testfn(-2, 3) - - + + From arigo at codespeak.net Tue Oct 11 10:44:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 10:44:14 +0200 (CEST) Subject: [pypy-svn] r18367 - in pypy/dist/pypy: rpython rpython/module translator/c translator/c/src translator/c/test Message-ID: <20051011084414.6B17C27B6A@code1.codespeak.net> Author: arigo Date: Tue Oct 11 10:44:00 2005 New Revision: 18367 Added: pypy/dist/pypy/rpython/module/ll_stackless.py (contents, props changed) pypy/dist/pypy/translator/c/src/ll_stackless.h (contents, props changed) pypy/dist/pypy/translator/c/stackless.py (contents, props changed) Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/c/src/main.h pypy/dist/pypy/translator/c/test/test_standalone.py Log: (afa, valentino, adim, tismer, ale, arigo) Stackless-style stack-unwinding variant for GenC. Work in progress, intermediate check-in. For reference, see http://codespeak.net/svn/user/arigo/hack/misc/stackless.c Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Tue Oct 11 10:44:00 2005 @@ -206,6 +206,11 @@ declare(ros.environ, strnullannotation, 'll_os/environ') # ___________________________________________________________ +# stackless +from pypy.rpython import objectmodel +declare(objectmodel.stack_frames_depth, int, 'll_stackless/stack_frames_depth') + +# ___________________________________________________________ # the exceptions that can be implicitely raised by some operations standardexceptions = { TypeError : True, Added: pypy/dist/pypy/rpython/module/ll_stackless.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/module/ll_stackless.py Tue Oct 11 10:44:00 2005 @@ -0,0 +1,6 @@ +from pypy.rpython import objectmodel + + +def ll_stackless_stack_frames_depth(): + return objectmodel.stack_frames_depth() +ll_stackless_stack_frames_depth.suggested_primitive = True Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Tue Oct 11 10:44:00 2005 @@ -3,7 +3,7 @@ RPython-compliant way. """ -import new +import new, inspect def instantiate(cls): @@ -38,6 +38,9 @@ def hlinvoke(repr, llcallable, *args): raise TypeError, "hlinvoke is meant to be rtyped and not called direclty" +def stack_frames_depth(): + return len(inspect.stack()) + # ____________________________________________________________ Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Oct 11 10:44:00 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, ll_strtod +from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod, ll_stackless from pypy.module.thread.rpython import ll_thread @@ -49,6 +49,7 @@ 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', + ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', } #______________________________________________________ Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Tue Oct 11 10:44:00 2005 @@ -22,7 +22,8 @@ cpython_exc more_ll_values vars - lltypes""".split() + lltypes + currentblock""".split() def __init__(self, graph, db, cpython_exc=False): self.graph = graph @@ -214,6 +215,7 @@ # generate the body of each block push_alive_op_result = self.gcpolicy.push_alive_op_result for block in allblocks: + self.currentblock = block myblocknum = blocknum[block] yield '' yield 'block%d:' % myblocknum @@ -395,14 +397,16 @@ def OP_DIRECT_CALL(self, op, err): # skip 'void' arguments args = [self.expr(v) for v in op.args if self.lltypemap(v) is not Void] - if self.lltypemap(op.result) is Void: + line = '%s(%s);' % (args[0], ', '.join(args[1:])) + if self.lltypemap(op.result) is not Void: # skip assignment of 'void' return value - 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);' % ( - r, args[0], ', '.join(args[1:]), err) + line = '%s = %s' % (r, line) + line = '%s %s' % (line, self.check_directcall_result(op, err)) + return line + + def check_directcall_result(self, op, err): + return 'if (RPyExceptionOccurred()) FAIL(%s);' % err # low-level operations def generic_get(self, op, sourceexpr): Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Oct 11 10:44:00 2005 @@ -48,6 +48,10 @@ exports = {translator.entrypoint.func_name: pf}, symboltable = self.symboltable) else: + if self.stackless: + from pypy.translator.c.stackless import StacklessData + db.stacklessdata = StacklessData() + defines['USE_STACKLESS'] = '1' cfile, extra = gen_source_standalone(db, modulename, targetdir, entrypointname = pfname, defines = defines) @@ -91,6 +95,7 @@ class CStandaloneBuilder(CBuilder): standalone = True executable_name = None + stackless = False def getentrypointptr(self): # XXX check that the entrypoint has the correct @@ -302,6 +307,9 @@ fc.close() print >> f + if hasattr(self.database, 'stacklessdata'): + self.database.stacklessdata.writefiles(self) + # this function acts as the fallback for small sources for now. # Maybe we drop this completely if source splitting is the way # to go. Currently, I'm quite fine with keeping a working fallback. Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Oct 11 10:44:00 2005 @@ -529,7 +529,12 @@ fnobj._callable,) elif hasattr(fnobj, 'graph'): cpython_exc = getattr(fnobj, 'exception_policy', None) == "CPython" - return FunctionCodeGenerator(fnobj.graph, db, cpython_exc) + if hasattr(db, 'stacklessdata'): + from pypy.translator.c.stackless import SlpFunctionCodeGenerator + gencls = SlpFunctionCodeGenerator + else: + gencls = FunctionCodeGenerator + return gencls(fnobj.graph, db, cpython_exc) elif getattr(fnobj, 'external', None) == 'C': # deprecated case if getattr(fnobj, 'includes', None): 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 Tue Oct 11 10:44:00 2005 @@ -38,6 +38,7 @@ # include "src/ll_math.h" # include "src/ll_strtod.h" # include "src/ll_thread.h" +# include "src/ll_stackless.h" #endif #ifdef PYPY_STANDALONE Added: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 10:44:00 2005 @@ -0,0 +1,134 @@ + +#ifdef USE_STACKLESS + +#ifndef PYPY_STANDALONE +# error "Stackless support: only for stand-alone executables" +#endif + +#define STANDALONE_ENTRY_POINT slp_standalone_entry_point + + +typedef struct slp_frame_s { + struct slp_frame_s *f_back; + int state; +} slp_frame_t; + +struct slp_state_decoding_entry_s { + void *function; + int signature; +}; + +slp_frame_t* slp_frame_stack_top = NULL; +slp_frame_t* slp_frame_stack_bottom = NULL; +int slp_restart_substate; +long slp_retval_long; +void *slp_retval_ptr; +slp_frame_t* slp_new_frame(int size, int state); + + +void slp_main_loop(void) +{ + int state, signature; + slp_frame_t* pending; + slp_frame_t* back; + void* fn; + + while (1) + { + slp_frame_stack_bottom = NULL; + pending = slp_frame_stack_top; + + while (1) + { + back = pending->f_back; + state = pending->state; + fn = slp_state_decoding_table[state].function; + signature = slp_state_decoding_table[state].signature; + if (fn != NULL) + slp_restart_substate = 0; + else + { + slp_restart_substate = signature; + state -= signature; + fn = slp_state_decoding_table[state].function; + signature = slp_state_decoding_table[state].signature; + } + + switch (signature) { + + case -1: + slp_retval_long = ((long(*)(void)) fn) (); + break; + +#include "slp_signatures.h" + + } + + free(pending); /* consumed by the previous call */ + if (slp_frame_stack_bottom) + break; + if (!back) + return; + pending = back; + slp_frame_stack_top = pending; + } + assert(slp_frame_stack_bottom->f_back == NULL); + slp_frame_stack_bottom->f_back = back; + } +} + +slp_frame_t* slp_new_frame(int size, int state) +{ + slp_frame_t* f = (slp_frame_t*) malloc(size); + f->f_back = NULL; + f->state = state; + return f; +} + +int slp_standalone_entry_point(RPyListOfString *argv) +{ + int result = PYPY_STANDALONE(argv); + if (slp_frame_stack_bottom) { + slp_main_loop(); + result = (int) slp_retval_long; + } + return result; +} + + +/* example function for testing */ + +long LL_stackless_stack_frames_depth(void) +{ + if (slp_frame_stack_top) goto resume; + + slp_frame_stack_top = slp_frame_stack_bottom = + slp_new_frame(sizeof(slp_frame_t), 0); + return -1; + + resume: + { + slp_frame_t* f = slp_frame_stack_top; + int result; + slp_frame_stack_top = NULL; + + result = 0; + while (f) { + result++; + f = f->f_back; + } + return result; + } +} + + +struct slp_state_decoding_entry_s slp_state_decoding_table[] = { + { LL_stackless_stack_frames_depth, -1 }, /* 0 */ + /* XXX WARNING FOR NOW MAKE SURE StacklessData.globalstatecounter + counts the number of manually-inserted lines above !!!!!!!!!! */ +#include "slp_state_decoding.h" +}; + +#include "slp_defs.h" + +#endif USE_STACKLESS 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 Oct 11 10:44:00 2005 @@ -1,5 +1,7 @@ -#define STANDALONE_ENTRY_POINT PYPY_STANDALONE +#ifndef STANDALONE_ENTRY_POINT +# define STANDALONE_ENTRY_POINT PYPY_STANDALONE +#endif char *RPython_StartupCode(void); /* forward */ Added: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 10:44:00 2005 @@ -0,0 +1,169 @@ +"""Stackless-style code generator. + +This produces C source in the style that was manually experimented +with in http://codespeak.net/svn/user/arigo/hack/misc/stackless.c +""" + +import py +from pypy.translator.c.funcgen import FunctionCodeGenerator + + +class StacklessData: + + def __init__(self): + self.frame_types = {} + self.globalstatecounter = 1 + + def get_frame_type(self, n_integers, n_floats, n_pointers): + key = n_integers, n_floats, n_pointers + try: + return self.frame_types[key] + except KeyError: + name = 'slp_frame_%d_%d_%d_s' % key + self.frame_types[key] = name + return name + + def writefiles(self, sg): + f = sg.makefile('slp_defs.h') + items = self.frame_types.items() + items.sort() + for (n_integers, n_floats, n_pointers), structname in items: + types = (['long']*n_integers + + ['double']*n_floats + + ['void *']*n_pointers) + varnames = (['l%d;' % i for i in range(n_integers)] + + ['d%d;' % i for i in range(n_floats)] + + ['p%d;' % i for i in range(n_pointers)]) + fields = [] + for type, varname in zip(types, varnames): + fields.append('%s %s;' % (type, varname)) + print >> f, 'struct %s { slp_frame_t header; %s };' % ( + structname, ' '.join(fields)) + + arguments = ['int state'] + saving_lines = [] + for type, varname in zip(types, varnames): + arguments.append('%s %s' % (type, varname)) + saving_lines.append('((struct %s*) f)->%s = %s;' % ( + structname, varname, varname)) + + code = str(py.code.Source(''' + void *save_%(name)s(%(arguments)s) + { + frame_t* f = new_frame(sizeof(struct %(name)s), state); + frame_stack_bottom->f_back = f; + frame_stack_bottom = f; + %(saving_lines)s + return NULL; + } + ''')) + print >> f, code % {'name': structname, + 'arguments': ', '.join(arguments), + 'saving_lines': '\n'.join(saving_lines)} + + f.close() + f = sg.makefile('slp_signatures.h') + ... + f.close() + f = sg.makefile('slp_XXX.h') + ... + f.close() + + +class SlpFunctionCodeGenerator(FunctionCodeGenerator): + + def cfunction_body(self): + # lists filled by check_directcall_result() from super.cfunction_body() + self.savelines = [] + self.resumeblocks = [] + body = list(super(SlpFunctionCodeGenerator, self).cfunction_body()) + # + if self.savelines: # header (if we need to resume) + yield 'if (slp_frame_stack_top) goto resume;' + for line in body: # regular body + yield line + if self.savelines: + yield '' + for line in self.savelines: # save-state-away lines + yield line + yield '' + yield 'resume:' # resume-state blocks + yield '{' + yield '\tslp_frame_t* f = slp_frame_stack_top;' + yield '\tslp_frame_stack_top = NULL;' + yield '\tswitch (slp_restart_substate) {' + for block in self.resumeblocks: + for line in block: + yield line + yield '\t}' + yield '\tassert(!"bad restart_substate");' + yield '}' + del self.savelines + del self.resumeblocks + + def check_directcall_result(self, op, err): + block = self.currentblock + curpos = block.operations.index(op) + + # XXX obscure: find all variables that are produced before 'op' + # and still used by or after 'op'. + produced = {} + for v in block.inputargs: + produced[v] = True + for op1 in block.operations[:curpos]: + produced[op1.result] = True + consumed = {} + for op1 in block.operations[curpos:]: + for v in op1: + if isinstance(v, Variable): + consumed[v] = True + if isinstance(block.exitswitch, Variable): + consumed[block.exitswitch] = True + for link in block.exits: + for v in link.args: + if isinstance(v, Variable): + consumed[v] = True + vars = [v for v in produced if v in consumed] + + # get the simplified frame struct that can store these vars + counts = {"long": [], + "double": [], + "void*": []} + for v in vars: + st = simplified_type(v.concretetype) + if st is not None: # ignore the Voids + counts[st].append('(%s)%s' % (st, self.expr(v))) + structname = self.get_frame_type(len(counts["long"]), + len(counts["double"]), + len(counts["void*"])) + + # reorder the vars according to their type + vars = counts["long"] + counts["double"] + counts["void*"] + + # generate the 'save:' line + label = 'save_%d' % len(self.savelines) + arguments = ['%d' % self.globalstatecounter] + vars + self.savelines.append('%s: return (%s) save_%s(%s);' % ( + label, + self.lltypename(self.graph.getreturnvar()).replace('@', ''), + structname, + ', '.join(arguments)) + + save_0: return (int) save_frame_1(0, n); + + + ... + ... + + +def simplified_type(T): + if T is lltype.Void: + return None + elif T is lltype.Float: + return "double" + elif isinstance(T, lltype.Primitive): + return "long" # large enough for all other primitives + elif isinstance(T, lltype.Ptr): + return "void*" + else: + raise Exception("don't know about %r" % (T,)) Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 10:44:00 2005 @@ -2,6 +2,7 @@ from pypy.translator.tool.cbuild import build_executable from pypy.annotation.model import SomeList, SomeString from pypy.annotation.listdef import ListDef +from pypy.rpython.objectmodel import stack_frames_depth import os @@ -23,3 +24,28 @@ cbuilder.compile() data = cbuilder.cmdexec('hi there') assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') + + +def INPROGRESS_test_stack_unwind(): + def f(n): + if n > 0: + return f(n-1) + else: + return stack_frames_depth() + def entry_point(argv): + count0 = f(0) + count10 = f(10) + diff = count10 - count0 + os.write(1, str(diff)+"\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.stackless = True + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('') + assert data.strip() == '10' From tismer at codespeak.net Tue Oct 11 10:52:11 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 11 Oct 2005 10:52:11 +0200 (CEST) Subject: [pypy-svn] r18370 - pypy/dist/pypy/translator/goal Message-ID: <20051011085211.D0EE527B6A@code1.codespeak.net> Author: tismer Date: Tue Oct 11 10:52:10 2005 New Revision: 18370 Modified: pypy/dist/pypy/translator/goal/driver.py pypy/dist/pypy/translator/goal/unixcheckpoint.py Log: added checkpoint support for windows. You need to install some VM like VMware. Then you can save a restartable snapshot using fork-before. Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Tue Oct 11 10:52:10 2005 @@ -339,8 +339,8 @@ prereq = getattr(self, 'prereq_checkpt_%s' % goal, None) if prereq: prereq() - from pypy.translator.goal import unixcheckpoint - unixcheckpoint.restartable_point(auto='run') + from pypy.translator.goal import unixcheckpoint + unixcheckpoint.restartable_point(auto='run') from pypy.translator.tool.util import mkexename, assert_rtyper_not_imported Modified: pypy/dist/pypy/translator/goal/unixcheckpoint.py ============================================================================== --- pypy/dist/pypy/translator/goal/unixcheckpoint.py (original) +++ pypy/dist/pypy/translator/goal/unixcheckpoint.py Tue Oct 11 10:52:10 2005 @@ -1,12 +1,14 @@ -import os +import os, sys def restart_process(): import sys os.execv(sys.executable, [sys.executable] + sys.argv) -def restartable_point(auto=None): +def restartable_point_fork(auto=None, extra_msg=None): while True: while True: + if extra_msg: + print extra_msg print '---> Checkpoint: cont / restart / quit / pdb ?' if auto: print 'auto-%s' % (auto,) @@ -27,7 +29,11 @@ if line == 'restart': restart_process() - pid = os.fork() + try: + pid = os.fork() + except AttributeError: + # windows case + return if pid != 0: # in parent while True: @@ -52,6 +58,18 @@ print '_'*78 break +# special version for win32 which does not have fork() at all, +# but epople can simulate it by hand using VMware + +def restartable_point_nofork(auto=None): + # auto ignored, no way to automate VMware, yet + restartable_point_fork(None, '+++ this system does not support fork +++\n' + 'if you have a virtual machine, you can save a snapshot now') + +if sys.platform == 'win32': + restartable_point = restartable_point_nofork +else: + restartable_point = restartable_point_fork if __name__ == '__main__': print 'doing stuff...' From mwh at codespeak.net Tue Oct 11 10:53:47 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 10:53:47 +0200 (CEST) Subject: [pypy-svn] r18372 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051011085347.2497827B6A@code1.codespeak.net> Author: mwh Date: Tue Oct 11 10:53:45 2005 New Revision: 18372 Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Log: Fix label copying around in func_builder (only affects dumping of output, I think/hope). Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/func_builder.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Tue Oct 11 10:53:45 2005 @@ -81,9 +81,9 @@ ourcode.label(FAST_ENTRY_LABEL) # err, should be an Assembler method: - l = code.labels.copy() - for k in l: - l[k] += 4*len(ourcode.insts) + l = {} + for k in code.labels: + l[k] = code.labels[k] + 4*len(ourcode.insts) r = code.rlabels.copy() for k in code.rlabels: r[k + 4*len(ourcode.insts)] = code.rlabels[k] From mwh at codespeak.net Tue Oct 11 10:56:38 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 10:56:38 +0200 (CEST) Subject: [pypy-svn] r18373 - in pypy/dist/pypy/translator/asm: . test Message-ID: <20051011085638.7B1D327B6A@code1.codespeak.net> Author: mwh Date: Tue Oct 11 10:56:36 2005 New Revision: 18373 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: Miscellaneous cleanups including activating backend_optimizations and allowing for the fact that distinct Variables may have the same names. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 11 10:56:36 2005 @@ -45,11 +45,11 @@ self.graph = graph self.allblocks = [] self.blocknum = {} - def visit(block): - if isinstance(block, Block): - self.allblocks.append(block) - self.blocknum[block] = len(self.blocknum) - traverse(visit, graph) + + for block in graph.iterblocks(): + self.allblocks.append(block) + self.blocknum[block] = len(self.blocknum) + self._var2reg = {} self.next_register = 3 for var in graph.startblock.inputargs: @@ -58,85 +58,88 @@ self._block_counter = 0 self.assembler = PPCAssembler() - - - def assign_register(self, var): assert var not in self._var2reg - self._var2reg[var] = self.next_register + self._var2reg[var.name] = self.next_register self.next_register += 1 def reg(self, var): assert isinstance(var, Variable) - if var not in self._var2reg: + if var.name not in self._var2reg: self.assign_register(var) - return self._var2reg[var] + return self._var2reg[var.name] def blockname(self): self._block_counter += 1 return 'anonblock' + str(self._block_counter) def genlinkcode(self, link): + A = self.assembler for s, t in zip(link.args, link.target.inputargs): - self.assembler.mr(self.reg(t), self.reg(s)) - self.assembler.b('block' + str(self.blocknum[link.target])) + if s.name != t.name: + A.mr(self.reg(t), self.reg(s)) + A.b('block' + str(self.blocknum[link.target])) def genblockcode(self, block): - self.assembler.label('block'+str(self.blocknum[block])) + A = self.assembler + A.label('block'+str(self.blocknum[block])) for op in block.operations: - print self.reg(op.result), op, op.args getattr(self, op.opname)(op.result, *op.args) assert len(block.exits) in [0, 1, 2] if len(block.exits) == 2: assert block.exitswitch is not None truelink, falselink = block.exits b = self.blockname() - self.assembler.cmpwi(0, self.reg(block.exitswitch), 1) - self.assembler.bne(b) + A.cmpwi(0, self.reg(block.exitswitch), 1) + A.bne(b) self.genlinkcode(truelink) - self.assembler.label(b) + A.label(b) self.genlinkcode(falselink) elif len(block.exits) == 1: self.genlinkcode(block.exits[0]) else: - self.assembler.mr(3, self.reg(block.inputargs[0])) - self.assembler.blr() + A.mr(3, self.reg(block.inputargs[0])) + A.blr() def gencode(self): #print map(self.reg, self.graph.startblock.inputargs) for block in self.allblocks: self.genblockcode(block) + def int_add(self, dest, v1, v2): + A = self.assembler if isinstance(v1, Constant): - self.assembler.addi(self.reg(dest), self.reg(v2), v1.value) + A.addi(self.reg(dest), self.reg(v2), v1.value) elif isinstance(v2, Constant): - self.assembler.addi(self.reg(dest), self.reg(v1), v2.value) + A.addi(self.reg(dest), self.reg(v1), v2.value) else: - self.assembler.add(self.reg(dest), self.reg(v1), self.reg(v2)) + A.add(self.reg(dest), self.reg(v1), self.reg(v2)) def int_sub(self, dest, v1, v2): + A = self.assembler if isinstance(v1, Constant): - self.assembler.subfi(self.reg(dest), self.reg(v2), v1.value) + A.subfi(self.reg(dest), self.reg(v2), v1.value) elif isinstance(v2, Constant): - self.assembler.addi(self.reg(dest), self.reg(v1), -v2.value) + A.addi(self.reg(dest), self.reg(v1), -v2.value) else: - self.assembler.sub(self.reg(dest), self.reg(v1), self.reg(v2)) + A.sub(self.reg(dest), self.reg(v1), self.reg(v2)) def int_gt(self, dest, v1, v2): + A = self.assembler conditional = 'bgt' if isinstance(v1, Constant): conditional = 'ble' - self.assembler.cmpwi(0, self.reg(v2), v1.value) + A.cmpwi(0, self.reg(v2), v1.value) elif isinstance(v2, Constant): - self.assembler.cmpwi(0, self.reg(v1), v2.value) + A.cmpwi(0, self.reg(v1), v2.value) else: - self.assembler.cmpw(0, self.reg(v2), self.reg(v1)) + A.cmpw(0, self.reg(v2), self.reg(v1)) b = self.blockname() - self.assembler.xor(self.reg(dest), self.reg(dest), self.reg(dest)) + A.xor(self.reg(dest), self.reg(dest), self.reg(dest)) getattr(self.assembler, conditional)(b) - self.assembler.addi(self.reg(dest), self.reg(dest), 1) - self.assembler.label(b) + A.addi(self.reg(dest), self.reg(dest), 1) + A.label(b) def same_as(self, dest, v1): self.assembler.mr(self.reg(dest), self.reg(v1)) Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Tue Oct 11 10:56:36 2005 @@ -24,7 +24,7 @@ a.simplify() t.specialize() t.checkgraphs() -# t.backend_optimizations() + t.backend_optimizations() if view: t.view() return t.asmcompile(self.processor) @@ -46,5 +46,3 @@ assert f(2, 3) == testfn(2, 3) assert f(-2, 3) == testfn(-2, 3) - - From mwh at codespeak.net Tue Oct 11 10:57:49 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 10:57:49 +0200 (CEST) Subject: [pypy-svn] r18374 - pypy/dist/pypy/translator/asm Message-ID: <20051011085749.D229727B6A@code1.codespeak.net> Author: mwh Date: Tue Oct 11 10:57:48 2005 New Revision: 18374 Modified: pypy/dist/pypy/translator/asm/genasm.py Log: crude liveness analysis, commented out for now. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 11 10:57:48 2005 @@ -46,10 +46,34 @@ self.allblocks = [] self.blocknum = {} +## origins = {} +## lastuse = {} + +## opindex = 0 + for block in graph.iterblocks(): self.allblocks.append(block) self.blocknum[block] = len(self.blocknum) + +## for arg in block.inputargs: +## if op.result.name not in origins: +## origins[op.result.name] = opindex + +## for op in blocks: +## origins[op.result.name] = opindex +## for arg in op.args: +## if isinstance(arg, Variable): +## lastuse[arg.name] = opindex +## opindex += 1 + +## liveranges = [] + +## for n in origins: +## if n not in lastuse: +## continue +## liveranges.append((lastuse[n], origins[n], n)) + self._var2reg = {} self.next_register = 3 for var in graph.startblock.inputargs: From boria at codespeak.net Tue Oct 11 11:06:16 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Tue, 11 Oct 2005 11:06:16 +0200 (CEST) Subject: [pypy-svn] r18375 - in pypy/dist/pypy/rpython/ootype: . test Message-ID: <20051011090616.B507727B5D@code1.codespeak.net> Author: boria Date: Tue Oct 11 11:06:16 2005 New Revision: 18375 Modified: pypy/dist/pypy/rpython/ootype/ootype.py pypy/dist/pypy/rpython/ootype/test/test_ootype.py Log: * Null values: checkpoint. Modified: pypy/dist/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/ootype.py Tue Oct 11 11:06:16 2005 @@ -169,9 +169,30 @@ self.__dict__[name] = value +class _null_instance(_instance): + + def __init__(self, CLASS): + _instance.__init__(self, CLASS) + + def __getattribute__(self, name): + if name.startswith("_"): + return object.__getattribute__(self, name) + + _instance.__getattr__(self, name) + + raise RuntimeError("Access to field in null object") + + def __setattr__(self, name, value): + _instance.__setattr__(self, name, value) + + raise RuntimeError("Assignment to field in null object") + def new(CLASS): return _instance(CLASS) +def null(CLASS): + return _null_instance(CLASS) + def typeOf(val): try: return val._TYPE Modified: pypy/dist/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 11:06:16 2005 @@ -23,3 +23,11 @@ assert c.a == 3 py.test.raises(TypeError, "Class('test', None, {'a': (Signed, 3.0)})") + +def test_simple_null(): + C = Class("test", None, {"a": Signed}) + + c = null(C) + assert typeOf(c) == C + + py.test.raises(RuntimeError, "c.a") From mwh at codespeak.net Tue Oct 11 11:15:42 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 11:15:42 +0200 (CEST) Subject: [pypy-svn] r18376 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051011091542.8046027B5D@code1.codespeak.net> Author: mwh Date: Tue Oct 11 11:15:40 2005 New Revision: 18376 Modified: pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py Log: make more code importable on non-PPC. Modified: pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/asmfunc.py Tue Oct 11 11:15:40 2005 @@ -1,7 +1,14 @@ import py -_ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() import mmap, struct +_ppcgen = None + +def get_ppcgen(): + global _ppcgen + if _ppcgen is None: + _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() + return _ppcgen + class AsmCode(object): def __init__(self, size): self.code = mmap.mmap(-1, size, @@ -10,7 +17,7 @@ def emit(self, insn): self.code.write(struct.pack('i', insn)) def __call__(self, *args): - return _ppcgen.mmap_exec(self.code, args) + return get_ppcgen().mmap_exec(self.code, args) def flush_cache(self): - _ppcgen.mmap_flush(self.code) - + get_ppcgen().mmap_flush(self.code) + Modified: pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/symbol_lookup.py Tue Oct 11 11:15:40 2005 @@ -1,11 +1,15 @@ -import py -_ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() +def lookup(sym): + global lookup + import py -try: - from _ppcgen import NSLookupAndBindSymbol + _ppcgen = py.magic.autopath().dirpath().join('_ppcgen.c').getpymodule() - def lookup(sym): - return NSLookupAndBindSymbol('_' + sym) -except ImportError: - from _ppcgen import dlsym as lookup + try: + from _ppcgen import NSLookupAndBindSymbol + + def lookup(sym): + return NSLookupAndBindSymbol('_' + sym) + except ImportError: + from _ppcgen import dlsym as lookup + return lookup(sym) From mwh at codespeak.net Tue Oct 11 11:17:48 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 11:17:48 +0200 (CEST) Subject: [pypy-svn] r18377 - pypy/dist/pypy/translator/asm Message-ID: <20051011091748.A4F7A27B57@code1.codespeak.net> Author: mwh Date: Tue Oct 11 11:17:47 2005 New Revision: 18377 Modified: pypy/dist/pypy/translator/asm/genasm.py Log: be a little more thorough at platform detection. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 11 11:17:47 2005 @@ -1,15 +1,28 @@ -import sys +import sys, os from pypy.objspace.flow.model import traverse, Block, Variable, Constant #Available Machine code targets (processor+operating system) +TARGET_UNKNOWN=0 TARGET_PPC=1 TARGET_WIN386=2 #set one of these -ASM_TARGET=TARGET_PPC +ASM_TARGET=TARGET_UNKNOWN #ASM_TARGET=TARGET_WIN386 +def determine_target(): + global ASM_TARGET + if sys.platform == 'darwin': + if os.uname()[-1] == 'Power Macintosh': + ASM_TARGET = TARGET_PPC + elif sys.platform == 'win32': + if 'Intel' in sys.version: + ASM_TARGET = TARGET_WIN386 + +determine_target() +if ASM_TARGET == TARGET_UNKNOWN: + raise Exception, 'Unknown Machine-code target specified.' if ASM_TARGET==TARGET_PPC: from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler @@ -17,13 +30,6 @@ elif ASM_TARGET==TARGET_WIN386: from pypy.translator.asm.i386gen.i386_assembler import i386Assembler as PPCAssembler #spoof system for time being from pypy.translator.asm.i386gen.i386_assembler import make_func -else: - raise Exception,'Unknown Machine-code target specified. Set ASM_TARGET=TARGET_XXXX ' - - -def genlinkcode(link): - for s, t in zip(link.args, link.target.inputargs): - print ' ', 'mr', t, s def genasm(translator): From boria at codespeak.net Tue Oct 11 11:52:59 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Tue, 11 Oct 2005 11:52:59 +0200 (CEST) Subject: [pypy-svn] r18379 - in pypy/dist/pypy/rpython/ootype: . test Message-ID: <20051011095259.B4B3D27B57@code1.codespeak.net> Author: boria Date: Tue Oct 11 11:52:59 2005 New Revision: 18379 Modified: pypy/dist/pypy/rpython/ootype/ootype.py pypy/dist/pypy/rpython/ootype/test/test_ootype.py Log: (Samuele, Bert, Arre, Aurelien, Boris) * Superclasses Modified: pypy/dist/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/ootype.py Tue Oct 11 11:52:59 2005 @@ -132,9 +132,23 @@ class Class(OOType): def __init__(self, name, superclass, fields): - self._fields = fields + self._superclass = superclass + + self._fields = {} + self._add_fields(fields) + + self._null = _null_instance(self) + + def _defl(self): + return self._null + + def _add_fields(self, fields): for name, defn in fields.iteritems(): + if self._superclass is not None: + if self._superclass._has_field(name): + raise TypeError("Field %r exists in superclass" % name) + if type(defn) is not tuple: fields[name] = (defn, defn._defl()) else: @@ -143,6 +157,29 @@ if ootype != typeOf(default): raise TypeError("Expected type %r for default" % ootype) + self._fields.update(fields) + + def _init_instance(self, instance): + if self._superclass is not None: + self._superclass._init_instance(instance) + + for name, (ootype, default) in self._fields.iteritems(): + instance.__dict__[name] = default + + def _has_field(self, name): + try: + self._fields[name] + return True + except KeyError: + if self._superclass is None: + return False + + return self._superclass._has_field(name) + + def _check_field(self, name): + if not self._has_field(name): + raise TypeError("No field named %r" % name) + # ____________________________________________________________ class _instance(object): @@ -150,14 +187,10 @@ def __init__(self, CLASS): self.__dict__["_TYPE"] = CLASS - for name, (ootype, default) in self._TYPE._fields.iteritems(): - self.__dict__[name] = default + CLASS._init_instance(self) def __getattr__(self, name): - try: - self._TYPE._fields[name] - except KeyError: - raise TypeError("No field named %r" % name) + self._TYPE._check_field(name) return self.__dict__[name] @@ -172,13 +205,13 @@ class _null_instance(_instance): def __init__(self, CLASS): - _instance.__init__(self, CLASS) + self.__dict__["_TYPE"] = CLASS def __getattribute__(self, name): if name.startswith("_"): return object.__getattribute__(self, name) - _instance.__getattr__(self, name) + self._TYPE._check_field(name) raise RuntimeError("Access to field in null object") @@ -191,7 +224,10 @@ return _instance(CLASS) def null(CLASS): - return _null_instance(CLASS) + return CLASS._null + +def addFields(CLASS, fields): + CLASS._add_fields(fields) def typeOf(val): try: Modified: pypy/dist/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 11:52:59 2005 @@ -31,3 +31,33 @@ assert typeOf(c) == C py.test.raises(RuntimeError, "c.a") + +def test_simple_class_field(): + C = Class("test", None, {}) + + D = Class("test2", None, {"a": C}) + d = new(D) + + assert typeOf(d.a) == C + + assert d.a == null(C) + +def test_simple_recursive_class(): + C = Class("test", None, {}) + + addFields(C, {"inst": C}) + + c = new(C) + assert c.inst == null(C) + +def test_simple_super(): + C = Class("test", None, {"a": (Signed, 3)}) + D = Class("test2", C, {}) + + d = new(D) + assert d.a == 3 + +def test_simple_field_shadowing(): + C = Class("test", None, {"a": (Signed, 3)}) + + py.test.raises(TypeError, """D = Class("test2", C, {"a": (Signed, 3)})""") From cfbolz at codespeak.net Tue Oct 11 12:17:01 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 11 Oct 2005 12:17:01 +0200 (CEST) Subject: [pypy-svn] r18381 - pypy/extradoc/publication Message-ID: <20051011101701.4273127B5B@code1.codespeak.net> Author: cfbolz Date: Tue Oct 11 12:16:58 2005 New Revision: 18381 Added: pypy/extradoc/publication/ pypy/extradoc/publication/PyPy Fact Sheet-v2.doc - copied unchanged from r18368, pypy/eu-tracking/deliverable/PyPy Fact Sheet-v2.doc pypy/extradoc/publication/PyPy Fact Sheet-v2.pdf - copied unchanged from r18368, pypy/eu-tracking/deliverable/PyPy Fact Sheet-v2.pdf Log: moving the fact sheets to extradoc From ericvrp at codespeak.net Tue Oct 11 12:20:25 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 11 Oct 2005 12:20:25 +0200 (CEST) Subject: [pypy-svn] r18382 - pypy/dist/pypy/translator/js Message-ID: <20051011102025.99D2927B5B@code1.codespeak.net> Author: ericvrp Date: Tue Oct 11 12:20:24 2005 New Revision: 18382 Removed: pypy/dist/pypy/translator/js/varsize.py Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/structnode.py Log: Added varsize array constructor. [57 passed, 106 failed] Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Tue Oct 11 12:20:24 2005 @@ -1,7 +1,6 @@ import py from pypy.rpython import lltype from pypy.translator.js.node import LLVMNode, ConstantLLVMNode -from pypy.translator.js import varsize from pypy.translator.js.log import log log = log.structnode @@ -28,8 +27,7 @@ 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.constructor_ref = 'new Array' self.constructor_decl = "%s(len)" % self.constructor_ref def __str__(self): @@ -50,12 +48,6 @@ # declaration for constructor codewriter.declare(self.constructor_decl) - def writeimpl(self, codewriter): - log.writeimpl(self.ref) - varsize.write_constructor(self.db, codewriter, self.ref, - self.constructor_decl, - self.array) - class VoidArrayTypeNode(LLVMNode): __slots__ = "db array ref".split() Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Tue Oct 11 12:20:24 2005 @@ -1,6 +1,5 @@ import py from pypy.translator.js.node import LLVMNode, ConstantLLVMNode -from pypy.translator.js import varsize from pypy.rpython import lltype from pypy.translator.js.log import log @@ -42,7 +41,7 @@ def __init__(self, db, struct): super(StructVarsizeTypeNode, self).__init__(db, struct) - prefix = '%new.varsizestruct.' + prefix = 'new_varsizestruct_' self.constructor_ref = self.make_ref(prefix, self.name) self.constructor_decl = "%s * %s(int %%len)" % \ (self.ref, @@ -71,12 +70,6 @@ name = current._names_without_voids()[-1] current = current._flds[name] assert isinstance(current, lltype.Array) - varsize.write_constructor(self.db, - codewriter, - self.ref, - self.constructor_decl, - current, - indices_to_array) class StructNode(ConstantLLVMNode): """ A struct constant. Can simply contain From arigo at codespeak.net Tue Oct 11 12:35:04 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 12:35:04 +0200 (CEST) Subject: [pypy-svn] r18383 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20051011103504.BB20D27B56@code1.codespeak.net> Author: arigo Date: Tue Oct 11 12:34:59 2005 New Revision: 18383 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/test/test_standalone.py Log: (tismer, valentino, ale, adim, arigo, afa) Progress on the Stackless-style code generation. Now all we're left with is a segfault to debug. Good :-) Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Oct 11 12:34:59 2005 @@ -89,6 +89,8 @@ if who_asks is not None: who_asks.dependencies[node] = True return 'struct %s @' % node.name + elif T.tag == 'rawmemory': + return 'void @' else: raise Exception("don't know about opaque type %r" % (T,)) else: Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Tue Oct 11 12:34:59 2005 @@ -23,13 +23,15 @@ more_ll_values vars lltypes + functionname currentblock""".split() - def __init__(self, graph, db, cpython_exc=False): + def __init__(self, graph, db, cpython_exc=False, functionname=None): self.graph = graph self.db = db self.gcpolicy = db.gcpolicy self.cpython_exc = cpython_exc + self.functionname = functionname # # collect all variables and constants used in the body, # and get their types now Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Oct 11 12:34:59 2005 @@ -38,6 +38,7 @@ modulename = uniquemodulename('testing') targetdir = udir.ensure(modulename, dir=1) + self.targetdir = targetdir defines = {} # defines={'COUNT_OP_MALLOCS': 1} if not self.standalone: @@ -110,7 +111,7 @@ python_inc = sysconfig.get_python_inc() self.executable_name = build_executable( [self.c_source_filename] + self.extrafiles, - include_dirs = [autopath.this_dir, python_inc], + include_dirs = [autopath.this_dir, python_inc, str(self.targetdir)], libraries=self.libraries) self._compiled = True return self.executable_name @@ -155,9 +156,8 @@ funcnodes.append(node) else: othernodes.append(node) - #if len(funcnodes) >= SPLIT_CRITERIA: - # always now - self.one_source_file = False + if len(funcnodes) >= SPLIT_CRITERIA: + self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes self.path = path @@ -307,9 +307,6 @@ fc.close() print >> f - if hasattr(self.database, 'stacklessdata'): - self.database.stacklessdata.writefiles(self) - # this function acts as the fallback for small sources for now. # Maybe we drop this completely if source splitting is the way # to go. Currently, I'm quite fine with keeping a working fallback. @@ -436,6 +433,10 @@ sg.set_strategy(targetdir) sg.gen_readable_parts_of_source(f) + # 2bis) stackless data + if hasattr(database, 'stacklessdata'): + database.stacklessdata.writefiles(sg) + # 3) start-up code print >> f gen_startupcode(f, database) Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Oct 11 12:34:59 2005 @@ -438,21 +438,21 @@ def __init__(self, db, T, obj): self.globalcontainer = True - self.funcgen = select_function_code_generator(obj, db) self.db = db self.T = T self.obj = obj - #self.dependencies = {} - self.typename = db.gettype(T) #, who_asks=self) - if self.funcgen: - argnames = self.funcgen.argnames() - self.implementationtypename = db.gettype(T, argnames=argnames) if hasattr(obj, 'includes'): self.includes = obj.includes self.name = self.basename() else: self.includes = () self.name = db.namespace.uniquename('g_' + self.basename()) + self.funcgen = select_function_code_generator(obj, db, self.name) + #self.dependencies = {} + self.typename = db.gettype(T) #, who_asks=self) + if self.funcgen: + argnames = self.funcgen.argnames() + self.implementationtypename = db.gettype(T, argnames=argnames) self.ptrname = self.name def basename(self): @@ -517,7 +517,7 @@ assert not USESLOTS or '__dict__' not in dir(FuncNode) -def select_function_code_generator(fnobj, db): +def select_function_code_generator(fnobj, db, functionname): if fnobj._callable in extfunc.EXTERNALS: # 'fnobj' is one of the ll_xyz() functions with the suggested_primitive # flag in pypy.rpython.module.*. The corresponding C wrappers are @@ -534,7 +534,7 @@ gencls = SlpFunctionCodeGenerator else: gencls = FunctionCodeGenerator - return gencls(fnobj.graph, db, cpython_exc) + return gencls(fnobj.graph, db, cpython_exc, functionname) elif getattr(fnobj, 'external', None) == 'C': # deprecated case if getattr(fnobj, 'includes', None): Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 12:34:59 2005 @@ -22,10 +22,51 @@ slp_frame_t* slp_frame_stack_bottom = NULL; int slp_restart_substate; long slp_retval_long; -void *slp_retval_ptr; +double slp_retval_double; +void *slp_retval_voidptr; slp_frame_t* slp_new_frame(int size, int state); +slp_frame_t* slp_new_frame(int size, int state) +{ + slp_frame_t* f = (slp_frame_t*) malloc(size); + f->f_back = NULL; + f->state = state; + return f; +} + + +/* example function for testing */ + +long LL_stackless_stack_frames_depth(void) +{ + if (slp_frame_stack_top) goto resume; + + slp_frame_stack_top = slp_frame_stack_bottom = + slp_new_frame(sizeof(slp_frame_t), 0); + return -1; + + resume: + { + slp_frame_t* f = slp_frame_stack_top; + int result; + slp_frame_stack_top = NULL; + + result = 0; + while (f) { + result++; + f = f->f_back; + } + return result; + } +} + + +#include "slp_defs.h" + +#include "slp_state_decoding.h" + + void slp_main_loop(void) { int state, signature; @@ -56,10 +97,6 @@ switch (signature) { - case -1: - slp_retval_long = ((long(*)(void)) fn) (); - break; - #include "slp_signatures.h" } @@ -77,14 +114,6 @@ } } -slp_frame_t* slp_new_frame(int size, int state) -{ - slp_frame_t* f = (slp_frame_t*) malloc(size); - f->f_back = NULL; - f->state = state; - return f; -} - int slp_standalone_entry_point(RPyListOfString *argv) { int result = PYPY_STANDALONE(argv); @@ -95,40 +124,4 @@ return result; } - -/* example function for testing */ - -long LL_stackless_stack_frames_depth(void) -{ - if (slp_frame_stack_top) goto resume; - - slp_frame_stack_top = slp_frame_stack_bottom = - slp_new_frame(sizeof(slp_frame_t), 0); - return -1; - - resume: - { - slp_frame_t* f = slp_frame_stack_top; - int result; - slp_frame_stack_top = NULL; - - result = 0; - while (f) { - result++; - f = f->f_back; - } - return result; - } -} - - -struct slp_state_decoding_entry_s slp_state_decoding_table[] = { - { LL_stackless_stack_frames_depth, -1 }, /* 0 */ - /* XXX WARNING FOR NOW MAKE SURE StacklessData.globalstatecounter - counts the number of manually-inserted lines above !!!!!!!!!! */ -#include "slp_state_decoding.h" -}; - -#include "slp_defs.h" - #endif USE_STACKLESS Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 12:34:59 2005 @@ -5,6 +5,8 @@ """ import py +from pypy.objspace.flow.model import Variable +from pypy.rpython import lltype from pypy.translator.c.funcgen import FunctionCodeGenerator @@ -13,6 +15,24 @@ def __init__(self): self.frame_types = {} self.globalstatecounter = 1 + self.allsignatures = {} + self.decode_table = [] + # start the decoding table with entries for the functions that + # are written manually in ll_stackless.h + self.registerunwindable('LL_stackless_stack_frames_depth', + lltype.FuncType([], lltype.Signed), + resume_points=1) + + def registerunwindable(self, functionname, FUNC, resume_points): + if resume_points >= 1: + try: + signum = self.allsignatures[FUNC] + except KeyError: + signum = len(self.allsignatures) + self.allsignatures[FUNC] = signum + self.decode_table.append((functionname, signum)) + for n in range(1, resume_points): + self.decode_table.append(('NULL', n)) def get_frame_type(self, n_integers, n_floats, n_pointers): key = n_integers, n_floats, n_pointers @@ -24,6 +44,7 @@ return name def writefiles(self, sg): + # generate slp_defs.h f = sg.makefile('slp_defs.h') items = self.frame_types.items() items.sort() @@ -31,9 +52,9 @@ types = (['long']*n_integers + ['double']*n_floats + ['void *']*n_pointers) - varnames = (['l%d;' % i for i in range(n_integers)] + - ['d%d;' % i for i in range(n_floats)] + - ['p%d;' % i for i in range(n_pointers)]) + varnames = (['l%d' % i for i in range(n_integers)] + + ['d%d' % i for i in range(n_floats)] + + ['v%d' % i for i in range(n_pointers)]) fields = [] for type, varname in zip(types, varnames): fields.append('%s %s;' % (type, varname)) @@ -48,25 +69,51 @@ structname, varname, varname)) code = str(py.code.Source(''' - void *save_%(name)s(%(arguments)s) - { - frame_t* f = new_frame(sizeof(struct %(name)s), state); - frame_stack_bottom->f_back = f; - frame_stack_bottom = f; - %(saving_lines)s - return NULL; - } + void *save_%(name)s(%(arguments)s) + { + slp_frame_t* f = slp_new_frame(sizeof(struct %(name)s), state); + slp_frame_stack_bottom->f_back = f; + slp_frame_stack_bottom = f; + %(saving_lines)s + return NULL; + } ''')) print >> f, code % {'name': structname, 'arguments': ', '.join(arguments), - 'saving_lines': '\n'.join(saving_lines)} - + 'saving_lines': '\n '.join(saving_lines)} f.close() + + # generate slp_signatures.h f = sg.makefile('slp_signatures.h') - ... + items = [(num, FUNC) for (FUNC, num) in self.allsignatures.items()] + items.sort() + for num, FUNC in items: + # 'FUNC' is a lltype.FuncType instance + print >> f, 'case %d:' % num + # XXX '0' is hopefully fine for a dummy value of any type + # for most compilers + dummyargs = ['0'] * len(FUNC.ARGS) + callexpr = '((%s) fn) (%s);' % ( + sg.database.gettype(lltype.Ptr(FUNC)).replace('@', ''), + ', '.join(dummyargs)) + globalretvalvartype = simplified_type(FUNC.RESULT) + if globalretvalvartype is not None: + globalretvalvarname = RETVALVARS[globalretvalvartype] + callexpr = '%s = (%s) %s' % (globalretvalvarname, + globalretvalvartype, + callexpr) + print >> f, '\t' + callexpr + print >> f, '\tbreak;' + print >> f f.close() - f = sg.makefile('slp_XXX.h') - ... + + # generate slp_state_decoding.h + f = sg.makefile('slp_state_decoding.h') + print >> f, 'static struct slp_state_decoding_entry_s', + print >> f, 'slp_state_decoding_table[] = {' + for i, (functionname, signum) in enumerate(self.decode_table): + print >> f, '/* %d */ { %s, %d },' % (i, functionname, signum) + print >> f, '};' f.close() @@ -94,14 +141,27 @@ yield '\tswitch (slp_restart_substate) {' for block in self.resumeblocks: for line in block: - yield line + yield '\t'+line yield '\t}' yield '\tassert(!"bad restart_substate");' yield '}' + + # record extra data needed to generate the slp_*.h tables: + # find the signatures of all functions + slpdata = self.db.stacklessdata + argtypes = [erase_ptr_type(v.concretetype) + for v in self.graph.getargs()] + argtypes = [T for T in argtypes if T is not lltype.Void] + rettype = erase_ptr_type(self.graph.getreturnvar().concretetype) + FUNC = lltype.FuncType(argtypes, rettype) + slpdata.registerunwindable(self.functionname, FUNC, + resume_points = len(self.resumeblocks)) + del self.savelines del self.resumeblocks def check_directcall_result(self, op, err): + stacklessdata = self.db.stacklessdata block = self.currentblock curpos = block.operations.index(op) @@ -114,7 +174,7 @@ produced[op1.result] = True consumed = {} for op1 in block.operations[curpos:]: - for v in op1: + for v in op1.args: if isinstance(v, Variable): consumed[v] = True if isinstance(block.exitswitch, Variable): @@ -129,31 +189,77 @@ counts = {"long": [], "double": [], "void*": []} + variables_to_restore = [] for v in vars: st = simplified_type(v.concretetype) if st is not None: # ignore the Voids - counts[st].append('(%s)%s' % (st, self.expr(v))) - structname = self.get_frame_type(len(counts["long"]), - len(counts["double"]), - len(counts["void*"])) + varname = self.expr(v) + # XXX hackish: the name of the field in the structure is + # computed from the 1st letter of the 'st' type, counting + # from 0 for each of the 'st' types independently + variables_to_restore.append((v, '%s%d' % ( + st[0], len(counts[st])))) + counts[st].append('(%s)%s' % (st, varname)) + structname = stacklessdata.get_frame_type(len(counts["long"]), + len(counts["double"]), + len(counts["void*"])) # reorder the vars according to their type vars = counts["long"] + counts["double"] + counts["void*"] - # generate the 'save:' line - label = 'save_%d' % len(self.savelines) - arguments = ['%d' % self.globalstatecounter] + vars + # generate the 'save:' line, e.g. + # save_0: return (int) save_frame_1(0, (long) n); + savelabel = 'save_%d' % len(self.savelines) + arguments = ['%d' % stacklessdata.globalstatecounter] + vars + stacklessdata.globalstatecounter += 1 self.savelines.append('%s: return (%s) save_%s(%s);' % ( - label, + savelabel, self.lltypename(self.graph.getreturnvar()).replace('@', ''), structname, - ', '.join(arguments)) - - save_0: return (int) save_frame_1(0, n); - + ', '.join(arguments))) + + # generate the resume block, e.g. + # case 1: + # n = (long)(((struct frame_1_s*) f)->i1); + # b = (long) retval_long; + # goto resume_1; + resumelabel = 'resume_%d' % len(self.resumeblocks) + lines = ['case %d:' % len(self.resumeblocks)] + for v, fieldname in variables_to_restore: + varname = self.expr(v) + vartype = self.lltypename(v).replace('@', '') + lines.append('\t%s = (%s)(((struct %s*) f)->%s);' % ( + varname, vartype, structname, fieldname)) + retvarname = self.expr(op.result) + retvartype = self.lltypename(op.result).replace('@', '') + retvarst = simplified_type(op.result.concretetype) + if retvarst is not None: + globalretvalvarname = RETVALVARS[retvarst] + lines.append('\t%s = (%s) %s;' % ( + retvarname, retvartype, globalretvalvarname)) + lines.append('\tgoto %s;' % (resumelabel,)) + self.resumeblocks.append(lines) + + # add the checks for the unwinding case just after the directcall + # in the source + unwind_check = "if (slp_frame_stack_bottom) goto %s;" % (savelabel,) + exception_check = (super(SlpFunctionCodeGenerator, self) + .check_directcall_result(op, err)) + return '%s\n%s:\n%s' % (unwind_check, + resumelabel, + exception_check) + + +def erase_ptr_type(T): + """Return T unless it's a pointer type, in which case we return a general + basic pointer type. + """ + if isinstance(T, lltype.Ptr): + return ERASED_PTR_TYPE + else: + return T - ... - ... +ERASED_PTR_TYPE = lltype.Ptr(lltype.OpaqueType("rawmemory")) def simplified_type(T): @@ -167,3 +273,9 @@ return "void*" else: raise Exception("don't know about %r" % (T,)) + +RETVALVARS = { + "double": "slp_retval_double", + "long" : "slp_retval_long", + "void*" : "slp_retval_voidptr", + } Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== From arigo at codespeak.net Tue Oct 11 12:57:05 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 12:57:05 +0200 (CEST) Subject: [pypy-svn] r18384 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051011105705.207F327B56@code1.codespeak.net> Author: arigo Date: Tue Oct 11 12:57:01 2005 New Revision: 18384 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/stackless.py Log: (still same 6 people) Progressing on Stackless GenC. No more segfault, just garbage result instead. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Oct 11 12:57:01 2005 @@ -30,6 +30,10 @@ pf = self.getentrypointptr() db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicy=self.gcpolicy) + if self.stackless: + from pypy.translator.c.stackless import StacklessData + db.stacklessdata = StacklessData() + # we need a concrete gcpolicy to do this self.libraries += db.gcpolicy.gc_libraries() @@ -50,8 +54,6 @@ symboltable = self.symboltable) else: if self.stackless: - from pypy.translator.c.stackless import StacklessData - db.stacklessdata = StacklessData() defines['USE_STACKLESS'] = '1' cfile, extra = gen_source_standalone(db, modulename, targetdir, entrypointname = pfname, Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 12:57:01 2005 @@ -30,6 +30,7 @@ slp_frame_t* slp_new_frame(int size, int state) { slp_frame_t* f = (slp_frame_t*) malloc(size); + assert(f != NULL); /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ f->f_back = NULL; f->state = state; return f; Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 12:57:01 2005 @@ -228,16 +228,16 @@ for v, fieldname in variables_to_restore: varname = self.expr(v) vartype = self.lltypename(v).replace('@', '') - lines.append('\t%s = (%s)(((struct %s*) f)->%s);' % ( + lines.append('%s = (%s)(((struct %s*) f)->%s);' % ( varname, vartype, structname, fieldname)) retvarname = self.expr(op.result) retvartype = self.lltypename(op.result).replace('@', '') retvarst = simplified_type(op.result.concretetype) if retvarst is not None: globalretvalvarname = RETVALVARS[retvarst] - lines.append('\t%s = (%s) %s;' % ( + lines.append('%s = (%s) %s;' % ( retvarname, retvartype, globalretvalvarname)) - lines.append('\tgoto %s;' % (resumelabel,)) + lines.append('goto %s;' % (resumelabel,)) self.resumeblocks.append(lines) # add the checks for the unwinding case just after the directcall @@ -245,9 +245,9 @@ unwind_check = "if (slp_frame_stack_bottom) goto %s;" % (savelabel,) exception_check = (super(SlpFunctionCodeGenerator, self) .check_directcall_result(op, err)) - return '%s\n%s:\n%s' % (unwind_check, - resumelabel, - exception_check) + return '%s\n %s:\n\t%s' % (unwind_check, + resumelabel, + exception_check) def erase_ptr_type(T): From mwh at codespeak.net Tue Oct 11 13:06:38 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 13:06:38 +0200 (CEST) Subject: [pypy-svn] r18385 - in pypy/dist/pypy/translator/asm: . test Message-ID: <20051011110638.DEF0127B57@code1.codespeak.net> Author: mwh Date: Tue Oct 11 13:06:36 2005 New Revision: 18385 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: pre-lunch checkin: we now make machine code for a simple infinitely registered machine. there's no implementation for this (yet?) so the tests are skipped for now. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 11 13:06:36 2005 @@ -1,6 +1,6 @@ import sys, os from pypy.objspace.flow.model import traverse, Block, Variable, Constant - +from pypy.translator.asm import infregmachine #Available Machine code targets (processor+operating system) TARGET_UNKNOWN=0 @@ -40,9 +40,8 @@ g = FuncGenerator(graph) g.gencode() - if ASM_TARGET==TARGET_WIN386: - g.assembler.dump() - return make_func(g.assembler, 'i', 'ii') + g.assembler.dump() + return lambda x,y:1#make_func(g.assembler, 'i', 'ii') class FuncGenerator(object): @@ -52,126 +51,87 @@ self.allblocks = [] self.blocknum = {} -## origins = {} -## lastuse = {} - -## opindex = 0 + self._var2reg = {} + self.next_register = 1 for block in graph.iterblocks(): self.allblocks.append(block) self.blocknum[block] = len(self.blocknum) - -## for arg in block.inputargs: -## if op.result.name not in origins: -## origins[op.result.name] = opindex - -## for op in blocks: -## origins[op.result.name] = opindex -## for arg in op.args: -## if isinstance(arg, Variable): -## lastuse[arg.name] = opindex -## opindex += 1 - -## liveranges = [] - -## for n in origins: -## if n not in lastuse: -## continue -## liveranges.append((lastuse[n], origins[n], n)) - - self._var2reg = {} - self.next_register = 3 - for var in graph.startblock.inputargs: - self.assign_register(var) - self._block_counter = 0 - self.assembler = PPCAssembler() + self.assembler = infregmachine.Assembler() + + for i, var in enumerate(graph.startblock.inputargs): + self.emit('LIA', self.reg(var), i) def assign_register(self, var): assert var not in self._var2reg self._var2reg[var.name] = self.next_register self.next_register += 1 + def emit(self, *args): + self.assembler.emit(*args) + def reg(self, var): - assert isinstance(var, Variable) - if var.name not in self._var2reg: - self.assign_register(var) - return self._var2reg[var.name] + if isinstance(var, Constant): + r = self.next_register + assert isinstance(var.value, int) + self.assembler.emit("LOAD", r, var.value) + self.next_register += 1 + return r + elif isinstance(var, Variable): + if var.name not in self._var2reg: + self.assign_register(var) + return self._var2reg[var.name] + else: + assert False, "reg of non-Variable, non-Constant!?" def blockname(self): self._block_counter += 1 return 'anonblock' + str(self._block_counter) + def blocktarget(self, block): + return 'block' + str(self.blocknum[block]) + def genlinkcode(self, link): A = self.assembler for s, t in zip(link.args, link.target.inputargs): if s.name != t.name: - A.mr(self.reg(t), self.reg(s)) - A.b('block' + str(self.blocknum[link.target])) + A.emit('MOV', self.reg(t), self.reg(s)) + A.emit('J', self.blocktarget(link.target)) def genblockcode(self, block): A = self.assembler - A.label('block'+str(self.blocknum[block])) - for op in block.operations: - getattr(self, op.opname)(op.result, *op.args) + A.label(self.blocktarget(block)) + assert len(block.exits) in [0, 1, 2] + + ordinaryops = block.operations[:] + if len(block.exits) == 2: + assert block.exitswitch is not None + assert block.operations[-1].result is block.exitswitch + del ordinaryops[-1] + + for op in ordinaryops: + A.emit(op.opname, self.reg(op.result), *map(self.reg, op.args)) + if len(block.exits) == 2: assert block.exitswitch is not None truelink, falselink = block.exits + lastop = block.operations[-1] + assert lastop.opname in ['int_gt', 'int_lt', 'int_ge'] + A.emit(lastop.opname, *map(self.reg, lastop.args)) b = self.blockname() - A.cmpwi(0, self.reg(block.exitswitch), 1) - A.bne(b) - self.genlinkcode(truelink) - A.label(b) + A.emit('JT', b) self.genlinkcode(falselink) + A.label(b) + self.genlinkcode(truelink) elif len(block.exits) == 1: self.genlinkcode(block.exits[0]) else: - A.mr(3, self.reg(block.inputargs[0])) - A.blr() + assert len(block.inputargs) == 1 + A.emit('RETPYTHON', self.reg(block.inputargs[0])) def gencode(self): - #print map(self.reg, self.graph.startblock.inputargs) for block in self.allblocks: self.genblockcode(block) - - - def int_add(self, dest, v1, v2): - A = self.assembler - if isinstance(v1, Constant): - A.addi(self.reg(dest), self.reg(v2), v1.value) - elif isinstance(v2, Constant): - A.addi(self.reg(dest), self.reg(v1), v2.value) - else: - A.add(self.reg(dest), self.reg(v1), self.reg(v2)) - - def int_sub(self, dest, v1, v2): - A = self.assembler - if isinstance(v1, Constant): - A.subfi(self.reg(dest), self.reg(v2), v1.value) - elif isinstance(v2, Constant): - A.addi(self.reg(dest), self.reg(v1), -v2.value) - else: - A.sub(self.reg(dest), self.reg(v1), self.reg(v2)) - - def int_gt(self, dest, v1, v2): - A = self.assembler - conditional = 'bgt' - if isinstance(v1, Constant): - conditional = 'ble' - A.cmpwi(0, self.reg(v2), v1.value) - elif isinstance(v2, Constant): - A.cmpwi(0, self.reg(v1), v2.value) - else: - A.cmpw(0, self.reg(v2), self.reg(v1)) - b = self.blockname() - A.xor(self.reg(dest), self.reg(dest), self.reg(dest)) - getattr(self.assembler, conditional)(b) - A.addi(self.reg(dest), self.reg(dest), 1) - A.label(b) - - def same_as(self, dest, v1): - self.assembler.mr(self.reg(dest), self.reg(v1)) - - Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Tue Oct 11 13:06:36 2005 @@ -5,6 +5,7 @@ class TestAsm(object): def setup_class(cls): + py.test.skip('broken broken broken') if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': py.test.skip('asm generation only on PPC') @@ -37,7 +38,7 @@ def test_int_add(self): def testfn(x=int, y=int): - z = 1 + x + z = 666 + x if z > 0: return x + y + z else: From arigo at codespeak.net Tue Oct 11 13:08:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 13:08:30 +0200 (CEST) Subject: [pypy-svn] r18386 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051011110830.C8AB327B57@code1.codespeak.net> Author: arigo Date: Tue Oct 11 13:08:27 2005 New Revision: 18386 Modified: pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/test/test_standalone.py Log: (tismer, valentino, ale, adim, arigo, afa) Stackless GenC: first test passes :-)) Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 13:08:27 2005 @@ -230,13 +230,13 @@ vartype = self.lltypename(v).replace('@', '') lines.append('%s = (%s)(((struct %s*) f)->%s);' % ( varname, vartype, structname, fieldname)) - retvarname = self.expr(op.result) - retvartype = self.lltypename(op.result).replace('@', '') - retvarst = simplified_type(op.result.concretetype) - if retvarst is not None: - globalretvalvarname = RETVALVARS[retvarst] - lines.append('%s = (%s) %s;' % ( - retvarname, retvartype, globalretvalvarname)) + retvarname = self.expr(op.result) + retvartype = self.lltypename(op.result).replace('@', '') + retvarst = simplified_type(op.result.concretetype) + if retvarst is not None: + globalretvalvarname = RETVALVARS[retvarst] + lines.append('%s = (%s) %s;' % ( + retvarname, retvartype, globalretvalvarname)) lines.append('goto %s;' % (resumelabel,)) self.resumeblocks.append(lines) Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 13:08:27 2005 @@ -26,7 +26,7 @@ assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') -def INPROGRESS_test_stack_unwind(): +def test_stack_unwind(): def f(n): if n > 0: return f(n-1) From ericvrp at codespeak.net Tue Oct 11 13:12:50 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 11 Oct 2005 13:12:50 +0200 (CEST) Subject: [pypy-svn] r18387 - pypy/dist/pypy/translator/js Message-ID: <20051011111250.20BB527B57@code1.codespeak.net> Author: ericvrp Date: Tue Oct 11 13:12:48 2005 New Revision: 18387 Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/node.py pypy/dist/pypy/translator/js/opwriter.py Log: * Fixed neg operation * Simplified codewriter binaryop * Simplified filenaming (we no longer have to import as Python module) * Fixed function naming when testing [72 passed, 91 failed] Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Tue Oct 11 13:12:48 2005 @@ -136,13 +136,11 @@ n += 1 def binaryop(self, name, targetvar, type_, ref1, ref2): - arithmetic = ('*', '/', '+', '-', '%', '^', '&', '|', '<<', '>>') - comparison = ('<', '<=', '==', '!=', '>=', '>') - if name in arithmetic or name in comparison: #XXX this should now always true - self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) - else: - self.llvm("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2)) + self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) + def neg(self, targetvar, source): + self.append('%(targetvar)s = -%(source)s' % locals()) + def call(self, targetvar, returntype, functionref, argrefs, argtypes, label=None, except_label=None): #args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) args = ", ".join(argrefs) Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Tue Oct 11 13:12:48 2005 @@ -16,6 +16,7 @@ from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir +from pypy.translator.js.node import LLVMNode from pypy.translator.js.database import Database from pypy.translator.js.codewriter import CodeWriter from pypy.translator.js.gc import GcPolicy @@ -24,13 +25,12 @@ class JS(object): # JS = Javascript - function_count = {} - def __init__(self, translator, function=None, gcpolicy=None, exceptionpolicy=None, debug=False): self.db = Database(self, translator) self.translator = translator self.gcpolicy = GcPolicy.new(gcpolicy) self.exceptionpolicy = ExceptionPolicy.new(exceptionpolicy) + LLVMNode.reset_nodename_count() #extfuncnode.ExternalFuncNode.used_external_functions = {} self.debug = debug # for debug we create comments of every operation that may be executed if debug: @@ -69,14 +69,7 @@ #if llexterns_header is None and using_external_functions: # llexterns_header, llexterns_functions = generate_llfile(self.db, extern_decls, support_functions, self.debug) - # prevent running the same function twice in a test - if func.func_name in self.function_count: - postfix = '_%d' % self.function_count[func.func_name] - self.function_count[func.func_name] += 1 - else: - postfix = '' - self.function_count[func.func_name] = 1 - self.filename = udir.join(func.func_name + postfix).new(ext='.js') + self.filename = udir.join(func.func_name).new(ext='.js') f = open(str(self.filename),'w') codewriter = CodeWriter(f, self) Modified: pypy/dist/pypy/translator/js/node.py ============================================================================== --- pypy/dist/pypy/translator/js/node.py (original) +++ pypy/dist/pypy/translator/js/node.py Tue Oct 11 13:12:48 2005 @@ -1,21 +1,28 @@ from pypy.rpython import lltype + +_nodename_count = {} + class LLVMNode(object): __slots__ = "".split() - nodename_count = {} + def reset_nodename_count(): + global _nodename_count + _nodename_count = {} + reset_nodename_count = staticmethod(reset_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 + + global _nodename_count + if name in _nodename_count: + postfix = '_%d' % _nodename_count[name] + _nodename_count[name] += 1 else: postfix = '' - self.nodename_count[name] = 1 + _nodename_count[name] = 1 return name + postfix def make_ref(self, prefix, name): Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Tue Oct 11 13:12:48 2005 @@ -64,7 +64,6 @@ 'ptr_ne': '!=', } - char_operations = {'char_lt': '<', 'char_le': '<=', 'char_eq': '==', @@ -133,11 +132,10 @@ keepalive = _skipped def int_abs(self, op): - functionref = '%' + op.opname - ExternalFuncNode.used_external_functions[functionref] = True + #ExternalFuncNode.used_external_functions[functionref] = True self.codewriter.call(self.db.repr_arg(op.result), self.db.repr_arg_type(op.result), - functionref, + 'Math.abs', [self.db.repr_arg(op.args[0])], [self.db.repr_arg_type(op.args[0])]) float_abs = int_abs @@ -149,22 +147,12 @@ def float_pow(self, op): self._generic_pow(op, "1.0") - def _generic_neg(self, op, zerostr): - self.codewriter.binaryop("sub", - self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), - zerostr, - self.db.repr_arg(op.args[0]), - ) - def int_neg(self, op): - 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") + def _generic_neg(self, op): + self.codewriter.neg(self.db.repr_arg(op.result), + self.db.repr_arg(op.args[0])) + int_neg = _generic_neg + uint_neg = _generic_neg + float_neg = _generic_neg def bool_not(self, op): self.codewriter.binaryop('^', From boria at codespeak.net Tue Oct 11 13:13:52 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Tue, 11 Oct 2005 13:13:52 +0200 (CEST) Subject: [pypy-svn] r18388 - in pypy/dist/pypy/rpython/ootype: . test Message-ID: <20051011111352.185C227B57@code1.codespeak.net> Author: boria Date: Tue Oct 11 13:13:51 2005 New Revision: 18388 Modified: pypy/dist/pypy/rpython/ootype/ootype.py pypy/dist/pypy/rpython/ootype/test/test_ootype.py Log: (Samuele, Arre, Bert, Boris, Aurelien) * Functions, methods Modified: pypy/dist/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/ootype.py Tue Oct 11 13:13:51 2005 @@ -131,12 +131,16 @@ class Class(OOType): - def __init__(self, name, superclass, fields): + def __init__(self, name, superclass, fields, methods=None): self._superclass = superclass self._fields = {} self._add_fields(fields) + if methods is None: + methods = {} + self._methods = methods + self._null = _null_instance(self) def _defl(self): @@ -150,10 +154,16 @@ raise TypeError("Field %r exists in superclass" % name) if type(defn) is not tuple: + if isinstance(defn, Meth): + raise TypeError("Attempting to store method in field") + fields[name] = (defn, defn._defl()) else: ootype, default = defn + if isinstance(ootype, Meth): + raise TypeError("Attempting to store method in field") + if ootype != typeOf(default): raise TypeError("Expected type %r for default" % ootype) @@ -180,6 +190,23 @@ if not self._has_field(name): raise TypeError("No field named %r" % name) + def _lookup(self, meth_name): + meth = self._methods.get(meth_name) + + # XXX superclass + + return meth + +class Func(OOType): + + def __init__(self, args, result): + self.ARGS = tuple(args) + self.RESULT = result + +class Meth(Func): + + def __init__(self, args, result): + Func.__init__(self, args, result) # ____________________________________________________________ class _instance(object): @@ -190,6 +217,10 @@ CLASS._init_instance(self) def __getattr__(self, name): + meth = self._TYPE._lookup(name) + if meth is not None: + return meth._bound(self) + self._TYPE._check_field(name) return self.__dict__[name] @@ -220,9 +251,62 @@ raise RuntimeError("Assignment to field in null object") +class _callable(object): + + def __init__(self, TYPE, **attrs): + self._TYPE = TYPE + self._name = "?" + self._callable = None + self.__dict__.update(attrs) + + def _checkargs(self, args): + if len(args) != len(self._TYPE.ARGS): + raise TypeError,"calling %r with wrong argument number: %r" % (self._TYPE, args) + + for a, ARG in zip(args, self._TYPE.ARGS): + if typeOf(a) != ARG: + raise TypeError,"calling %r with wrong argument types: %r" % (self._TYPE, args) + callb = self._callable + if callb is None: + raise RuntimeError,"calling undefined function" + return callb + +class _func(_callable): + + def __init__(self, FUNCTION, **attrs): + assert isinstance(FUNCTION, Func) + _callable.__init__(self, FUNCTION, **attrs) + + def __call__(self, *args): + return self._checkargs(args)(*args) + +class _meth(_callable): + + def __init__(self, METHOD, **attrs): + assert isinstance(METHOD, Meth) + _callable.__init__(self, METHOD, **attrs) + + def _bound(self, inst): + return _bound_meth(inst, self) + +class _bound_meth(object): + + def __init__(self, inst, meth): + self.inst = inst + self.meth = meth + + def __call__(self, *args): + return self.meth._checkargs(args)(self.inst, *args) + def new(CLASS): return _instance(CLASS) +def func(FUNCTION, **attrs): + return _func(FUNCTION, **attrs) + +def meth(METHOD, **attrs): + return _meth(METHOD, **attrs) + def null(CLASS): return CLASS._null Modified: pypy/dist/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 13:13:51 2005 @@ -61,3 +61,49 @@ C = Class("test", None, {"a": (Signed, 3)}) py.test.raises(TypeError, """D = Class("test2", C, {"a": (Signed, 3)})""") + +def test_simple_function(): + F = Func([Signed, Signed], Signed) + def f_(a, b): + return a+b + f = func(F, _name="f", _callable=f_) + assert typeOf(f) == F + + result = f(2, 3) + assert typeOf(result) == Signed + assert result == 5 + +def test_function_args(): + F = Func([Signed, Signed], Signed) + def f_(a, b): + return a+b + f = func(F, _name="f", _callable=f_) + + py.test.raises(TypeError, "f(2.0, 3.0)") + py.test.raises(TypeError, "f()") + py.test.raises(TypeError, "f(1, 2, 3)") + +def test_class_method(): + M = Meth([Signed], Signed) + def m_(self, b): + return self.a + b + m = meth(M, _name="m", _callable=m_) + + C = Class("test", None, {"a": (Signed, 2)}, {"m": m}) + c = new(C) + + assert c.m(3) == 5 + + py.test.raises(TypeError, "c.m(3.0)") + py.test.raises(TypeError, "c.m()") + py.test.raises(TypeError, "c.m(1, 2, 3)") + +def test_class_method_field_clash(): + M = Meth([Signed], Signed) + def m_(self, b): + return self.a + b + m = meth(M, _name="m", _callable=m_) + + py.test.raises(TypeError, """Class("test", None, {"a": M})""") + + py.test.raises(TypeError, """Class("test", None, {"m": Signed}, {"m":m})""") From tismer at codespeak.net Tue Oct 11 13:16:55 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 11 Oct 2005 13:16:55 +0200 (CEST) Subject: [pypy-svn] r18389 - pypy/dist/pypy/translator/c/src Message-ID: <20051011111655.4E56827B57@code1.codespeak.net> Author: tismer Date: Tue Oct 11 13:16:54 2005 New Revision: 18389 Modified: pypy/dist/pypy/translator/c/src/address.h (props changed) Log: eolstyle From arigo at codespeak.net Tue Oct 11 14:05:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 14:05:14 +0200 (CEST) Subject: [pypy-svn] r18390 - pypy/dist/pypy/translator/c Message-ID: <20051011120514.1D7C127B57@code1.codespeak.net> Author: arigo Date: Tue Oct 11 14:05:11 2005 New Revision: 18390 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/stackless.py Log: removed the hack Ptr(Opaque("rawmemory")) and replaced it with Address -- supported by genc since r18342. Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Oct 11 14:05:11 2005 @@ -89,8 +89,6 @@ if who_asks is not None: who_asks.dependencies[node] = True return 'struct %s @' % node.name - elif T.tag == 'rawmemory': - return 'void @' else: raise Exception("don't know about opaque type %r" % (T,)) else: Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 14:05:11 2005 @@ -7,6 +7,7 @@ import py from pypy.objspace.flow.model import Variable from pypy.rpython import lltype +from pypy.rpython.memory.lladdress import Address from pypy.translator.c.funcgen import FunctionCodeGenerator @@ -255,12 +256,10 @@ basic pointer type. """ if isinstance(T, lltype.Ptr): - return ERASED_PTR_TYPE + return Address else: return T -ERASED_PTR_TYPE = lltype.Ptr(lltype.OpaqueType("rawmemory")) - def simplified_type(T): if T is lltype.Void: From arigo at codespeak.net Tue Oct 11 14:13:19 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 14:13:19 +0200 (CEST) Subject: [pypy-svn] r18391 - pypy/dist/pypy/translator/c Message-ID: <20051011121319.ACD9427B57@code1.codespeak.net> Author: arigo Date: Tue Oct 11 14:13:16 2005 New Revision: 18391 Modified: pypy/dist/pypy/translator/c/genc.py Log: bugfix Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Oct 11 14:13:16 2005 @@ -15,6 +15,7 @@ c_source_filename = None _compiled = False symboltable = None + stackless = False def __init__(self, translator, gcpolicy=None, libraries=None): self.translator = translator @@ -98,7 +99,6 @@ class CStandaloneBuilder(CBuilder): standalone = True executable_name = None - stackless = False def getentrypointptr(self): # XXX check that the entrypoint has the correct From arigo at codespeak.net Tue Oct 11 14:41:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 14:41:44 +0200 (CEST) Subject: [pypy-svn] r18394 - pypy/extradoc/sprintinfo Message-ID: <20051011124144.DDA1E27B75@code1.codespeak.net> Author: arigo Date: Tue Oct 11 14:41:41 2005 New Revision: 18394 Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt Log: Tuesday status update. Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-planning.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-planning.txt Tue Oct 11 14:41:41 2005 @@ -12,19 +12,26 @@ thursday: breakday (for some of us: eu-consortium meeting) -pairing monday +pairing tuesday ======================= -stackless/cps: +stackless/cps: (same group continues, "re-"pairing inside) christian, armin Valentino, Amaury Adrien, Anders -andrew/michael: powerpc-backend +andrew/michael: powerpc-backend (getting there, continues) -bert, samuele, boris, arre, aurelien: different specialization to more HL-backends +bert, samuele, boris, arre, aurelien: different specialization to more HL-backends +(defined the "ootypes" model, like the "lltypes" but more OO-ish; will start + to work on the ootyper, as a branch of the rtyper for now; same group continues + and may split in two subgroups soon -- backend and ootyper.) -llinterpreter: Carl, NN (holger later) +llinterpreter: Carl, Holger +(starting on the data model of the ll flow graphs, continues) + + +next status meeting: wed 10:30 later wednesday: From cfbolz at codespeak.net Tue Oct 11 14:58:01 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 11 Oct 2005 14:58:01 +0200 (CEST) Subject: [pypy-svn] r18395 - pypy/dist/pypy/doc Message-ID: <20051011125801.BB04B27B5E@code1.codespeak.net> Author: cfbolz Date: Tue Oct 11 14:58:00 2005 New Revision: 18395 Modified: pypy/dist/pypy/doc/news.txt Log: news item about paris sprint Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Tue Oct 11 14:58:00 2005 @@ -9,19 +9,21 @@ .. _Python: http://www.python.org/doc/current/ref/ref.html .. _`more...`: http://codespeak.net/pypy/dist/pypy/doc/architecture.html#mission-statement -Next PyPy Sprint in Paris 10th-16th October 2005 -========================================================== +PyPy Sprint in Paris 10th-16th October 2005 +======================================================== -Our next sprint is going to focus on threads/GC, various -refactorings as well as JIT_ and `continuation-passing`_ style -translation of PyPy's Python interpreter. The `Paris Announcement`_ -details times and logistics as well as the registration procedure. -The number of people who can attend is somewhat limited so it's -good if you signal your interest as early as possible. +At the moment one of the biggest PyPy sprint ever is taking place: 18 people +are sitting in `Logilabs offices in Paris`_. We are happy to greet five new +developers to the PyPy Community! Currently we are focusing on implementing +`continuation-passing`_ style (stackless), making the translation process +work for target languages with more powerful object systems and some tiny +steps into the JIT_ direction. Michael and Carl have written +a `report about day one`_. *(10/11/2005)* -.. _`Paris Announcement`: http://codespeak.net/pypy/extradoc/sprintinfo/paris-2005-sprint.html +.. _`Logilabs offices in Paris`: http://codespeak.net/pypy/extradoc/sprintinfo/paris-2005-sprint.html .. _JIT: http://en.wikipedia.org/wiki/Just-in-time_compilation .. _`continuation-passing`: http://en.wikipedia.org/wiki/Continuation_passing_style +.. _`report about day one`: http://codespeak.net/pipermail/pypy-dev/2005q4/002510.html PyPy release 0.7.0 =================== From arigo at codespeak.net Tue Oct 11 15:02:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 15:02:02 +0200 (CEST) Subject: [pypy-svn] r18396 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051011130202.ECD2A27B6A@code1.codespeak.net> Author: arigo Date: Tue Oct 11 15:01:59 2005 New Revision: 18396 Modified: pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/test/test_standalone.py Log: Void special case: avoid generating code like 'return (void)save_frame(...);' Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 15:01:59 2005 @@ -213,11 +213,15 @@ savelabel = 'save_%d' % len(self.savelines) arguments = ['%d' % stacklessdata.globalstatecounter] + vars stacklessdata.globalstatecounter += 1 - self.savelines.append('%s: return (%s) save_%s(%s);' % ( - savelabel, - self.lltypename(self.graph.getreturnvar()).replace('@', ''), - structname, - ', '.join(arguments))) + savecall = 'save_%s(%s);' % (structname, ', '.join(arguments)) + retvar = self.graph.getreturnvar() + if retvar.concretetype is lltype.Void: + savecall += ' return;' + else: + savecall = 'return (%s) %s' % ( + self.lltypename(retvar).replace('@', ''), + savecall) + self.savelines.append('%s: %s' % (savelabel, savecall)) # generate the resume block, e.g. # case 1: Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 15:01:59 2005 @@ -27,11 +27,18 @@ def test_stack_unwind(): + def g1(): + "just to check Void special cases around the code" + def g2(ignored): + g1() def f(n): + g1() if n > 0: - return f(n-1) + res = f(n-1) else: - return stack_frames_depth() + res = stack_frames_depth() + g2(g1) + return res def entry_point(argv): count0 = f(0) count10 = f(10) From tismer at codespeak.net Tue Oct 11 15:03:08 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 11 Oct 2005 15:03:08 +0200 (CEST) Subject: [pypy-svn] r18397 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051011130308.9323827B6A@code1.codespeak.net> Author: tismer Date: Tue Oct 11 15:03:06 2005 New Revision: 18397 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/stackless.py Log: modified things for source splitting a bit. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Oct 11 15:03:06 2005 @@ -158,7 +158,7 @@ funcnodes.append(node) else: othernodes.append(node) - if len(funcnodes) >= SPLIT_CRITERIA: + if 1 or len(funcnodes) >= SPLIT_CRITERIA:##!! self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 15:03:06 2005 @@ -18,14 +18,31 @@ int signature; }; +#include "slp_defs.h" + +/* prototypes */ + +extern slp_frame_t* slp_frame_stack_top; +extern slp_frame_t* slp_frame_stack_bottom; +extern int slp_restart_substate; +extern long slp_retval_long; +extern double slp_retval_double; +extern void *slp_retval_voidptr; + +slp_frame_t* slp_new_frame(int size, int state); +long LL_stackless_stack_frames_depth(void); +void slp_main_loop(void); + +#ifndef PYPY_NOT_MAIN_FILE + +/* implementations */ + slp_frame_t* slp_frame_stack_top = NULL; slp_frame_t* slp_frame_stack_bottom = NULL; int slp_restart_substate; long slp_retval_long; double slp_retval_double; void *slp_retval_voidptr; -slp_frame_t* slp_new_frame(int size, int state); - slp_frame_t* slp_new_frame(int size, int state) { @@ -41,7 +58,8 @@ long LL_stackless_stack_frames_depth(void) { - if (slp_frame_stack_top) goto resume; + if (slp_frame_stack_top) + goto resume; slp_frame_stack_top = slp_frame_stack_bottom = slp_new_frame(sizeof(slp_frame_t), 0); @@ -62,9 +80,6 @@ } } - -#include "slp_defs.h" - #include "slp_state_decoding.h" @@ -125,4 +140,6 @@ return result; } +#endif /* PYPY_NOT_MAIN_FILE */ + #endif USE_STACKLESS Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 15:03:06 2005 @@ -46,7 +46,15 @@ def writefiles(self, sg): # generate slp_defs.h - f = sg.makefile('slp_defs.h') + fi = sg.makefile('slp_defs.h') + cname = 'slp_impl.c' + assert sg.uniquecname(cname) == cname + fc = sg.makefile(cname) + print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#include "common_header.h"' + for line in sg.preimpl: + print >> fc, line + print >> fc, '#include "src/g_include.h"' items = self.frame_types.items() items.sort() for (n_integers, n_floats, n_pointers), structname in items: @@ -59,7 +67,7 @@ fields = [] for type, varname in zip(types, varnames): fields.append('%s %s;' % (type, varname)) - print >> f, 'struct %s { slp_frame_t header; %s };' % ( + print >> fi, 'struct %s { slp_frame_t header; %s };' % ( structname, ' '.join(fields)) arguments = ['int state'] @@ -69,6 +77,7 @@ saving_lines.append('((struct %s*) f)->%s = %s;' % ( structname, varname, varname)) + head = 'void *save_%(name)s(%(arguments)s);' code = str(py.code.Source(''' void *save_%(name)s(%(arguments)s) { @@ -79,18 +88,21 @@ return NULL; } ''')) - print >> f, code % {'name': structname, - 'arguments': ', '.join(arguments), - 'saving_lines': '\n '.join(saving_lines)} - f.close() + argdict = {'name': structname, + 'arguments': ', '.join(arguments), + 'saving_lines': '\n '.join(saving_lines)} + print >> fi, head % argdict + print >> fc, code % argdict + fi.close() + fc.close() # generate slp_signatures.h - f = sg.makefile('slp_signatures.h') + fi = sg.makefile('slp_signatures.h') items = [(num, FUNC) for (FUNC, num) in self.allsignatures.items()] items.sort() for num, FUNC in items: # 'FUNC' is a lltype.FuncType instance - print >> f, 'case %d:' % num + print >> fi, 'case %d:' % num # XXX '0' is hopefully fine for a dummy value of any type # for most compilers dummyargs = ['0'] * len(FUNC.ARGS) @@ -103,19 +115,19 @@ callexpr = '%s = (%s) %s' % (globalretvalvarname, globalretvalvartype, callexpr) - print >> f, '\t' + callexpr - print >> f, '\tbreak;' - print >> f - f.close() + print >> fi, '\t' + callexpr + print >> fi, '\tbreak;' + print >> fi + fi.close() # generate slp_state_decoding.h - f = sg.makefile('slp_state_decoding.h') - print >> f, 'static struct slp_state_decoding_entry_s', - print >> f, 'slp_state_decoding_table[] = {' + fi = sg.makefile('slp_state_decoding.h') + print >> fi, 'static struct slp_state_decoding_entry_s', + print >> fi, 'slp_state_decoding_table[] = {' for i, (functionname, signum) in enumerate(self.decode_table): - print >> f, '/* %d */ { %s, %d },' % (i, functionname, signum) - print >> f, '};' - f.close() + print >> fi, '/* %d */ { %s, %d },' % (i, functionname, signum) + print >> fi, '};' + fi.close() class SlpFunctionCodeGenerator(FunctionCodeGenerator): From arigo at codespeak.net Tue Oct 11 15:06:16 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 15:06:16 +0200 (CEST) Subject: [pypy-svn] r18398 - pypy/dist/pypy/translator/c Message-ID: <20051011130616.CC82627B7B@code1.codespeak.net> Author: arigo Date: Tue Oct 11 15:06:14 2005 New Revision: 18398 Modified: pypy/dist/pypy/translator/c/stackless.py Log: We don't need .replace('@','') explicitely; there is cdecl() for that. Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 15:06:14 2005 @@ -8,6 +8,7 @@ from pypy.objspace.flow.model import Variable from pypy.rpython import lltype from pypy.rpython.memory.lladdress import Address +from pypy.translator.c.support import cdecl from pypy.translator.c.funcgen import FunctionCodeGenerator @@ -106,9 +107,9 @@ # XXX '0' is hopefully fine for a dummy value of any type # for most compilers dummyargs = ['0'] * len(FUNC.ARGS) - callexpr = '((%s) fn) (%s);' % ( - sg.database.gettype(lltype.Ptr(FUNC)).replace('@', ''), - ', '.join(dummyargs)) + functiontype = sg.database.gettype(lltype.Ptr(FUNC)) + callexpr = '((%s) fn) (%s);' % (cdecl(functiontype, ''), + ', '.join(dummyargs)) globalretvalvartype = simplified_type(FUNC.RESULT) if globalretvalvartype is not None: globalretvalvarname = RETVALVARS[globalretvalvartype] @@ -230,9 +231,9 @@ if retvar.concretetype is lltype.Void: savecall += ' return;' else: - savecall = 'return (%s) %s' % ( - self.lltypename(retvar).replace('@', ''), - savecall) + retvartype = self.lltypename(retvar) + savecall = 'return (%s) %s' % (cdecl(retvartype, ''), + savecall) self.savelines.append('%s: %s' % (savelabel, savecall)) # generate the resume block, e.g. @@ -244,16 +245,16 @@ lines = ['case %d:' % len(self.resumeblocks)] for v, fieldname in variables_to_restore: varname = self.expr(v) - vartype = self.lltypename(v).replace('@', '') + vartype = self.lltypename(v) lines.append('%s = (%s)(((struct %s*) f)->%s);' % ( - varname, vartype, structname, fieldname)) + varname, cdecl(vartype, ''), structname, fieldname)) retvarname = self.expr(op.result) - retvartype = self.lltypename(op.result).replace('@', '') + retvartype = self.lltypename(op.result) retvarst = simplified_type(op.result.concretetype) if retvarst is not None: globalretvalvarname = RETVALVARS[retvarst] lines.append('%s = (%s) %s;' % ( - retvarname, retvartype, globalretvalvarname)) + retvarname, cdecl(retvartype, ''), globalretvalvarname)) lines.append('goto %s;' % (resumelabel,)) self.resumeblocks.append(lines) From mwh at codespeak.net Tue Oct 11 15:42:17 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 15:42:17 +0200 (CEST) Subject: [pypy-svn] r18399 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051011134217.6138327B74@code1.codespeak.net> Author: mwh Date: Tue Oct 11 15:42:09 2005 New Revision: 18399 Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Log: add slwi (shift left word immediate) mnemonic. Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Tue Oct 11 15:42:09 2005 @@ -505,7 +505,8 @@ # F.4 Simplified Mnemonics for Rotate and Shift Instructions - + def slwi(self, rA, rS, n): + self.rlwinm(rA, rS, n, 0, 31-n) # F.5 Simplified Mnemonics for Branch Instructions From boria at codespeak.net Tue Oct 11 15:47:15 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Tue, 11 Oct 2005 15:47:15 +0200 (CEST) Subject: [pypy-svn] r18401 - in pypy/dist/pypy/rpython/ootype: . test Message-ID: <20051011134715.534E727B74@code1.codespeak.net> Author: boria Date: Tue Oct 11 15:47:15 2005 New Revision: 18401 Modified: pypy/dist/pypy/rpython/ootype/ootype.py pypy/dist/pypy/rpython/ootype/test/test_ootype.py Log: (Samuele, Arre, Aureliene, Bert, Boris) * More superclass work, method and field name clashes * Fixed indentation Modified: pypy/dist/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/ootype.py Tue Oct 11 15:47:15 2005 @@ -131,15 +131,14 @@ class Class(OOType): - def __init__(self, name, superclass, fields, methods=None): + def __init__(self, name, superclass, fields, methods={}): self._superclass = superclass + self._methods = {} self._fields = {} - self._add_fields(fields) - if methods is None: - methods = {} - self._methods = methods + self._add_fields(fields) + self._add_methods(methods) self._null = _null_instance(self) @@ -147,8 +146,10 @@ return self._null def _add_fields(self, fields): - for name, defn in fields.iteritems(): + if self._lookup(name) is not None: + raise TypeError("Cannot add field %r: method already exists" % name) + if self._superclass is not None: if self._superclass._has_field(name): raise TypeError("Field %r exists in superclass" % name) @@ -169,6 +170,12 @@ self._fields.update(fields) + def _add_methods(self, methods): + for name in methods: + if self._has_field(name): + raise TypeError("Can't add method %r: field already exists" % name) + self._methods.update(methods) + def _init_instance(self, instance): if self._superclass is not None: self._superclass._init_instance(instance) @@ -193,7 +200,8 @@ def _lookup(self, meth_name): meth = self._methods.get(meth_name) - # XXX superclass + if meth is None and self._superclass is not None: + meth = self._superclass._lookup(meth_name) return meth @@ -206,7 +214,7 @@ class Meth(Func): def __init__(self, args, result): - Func.__init__(self, args, result) + Func.__init__(self, args, result) # ____________________________________________________________ class _instance(object): @@ -265,6 +273,9 @@ for a, ARG in zip(args, self._TYPE.ARGS): if typeOf(a) != ARG: + if isinstance(ARG, Class) and isinstance(a, _instance): + if instanceof(a, ARG): + continue raise TypeError,"calling %r with wrong argument types: %r" % (self._TYPE, args) callb = self._callable if callb is None: @@ -278,7 +289,7 @@ _callable.__init__(self, FUNCTION, **attrs) def __call__(self, *args): - return self._checkargs(args)(*args) + return self._checkargs(args)(*args) class _meth(_callable): @@ -311,7 +322,19 @@ return CLASS._null def addFields(CLASS, fields): - CLASS._add_fields(fields) + CLASS._add_fields(fields) + +def addMethods(CLASS, methods): + CLASS._add_methods(methods) + +def instanceof(inst, CLASS): + c = inst._TYPE + while c is not None: + if c is CLASS: + return True + c = c._superclass + + return False def typeOf(val): try: Modified: pypy/dist/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 15:47:15 2005 @@ -63,47 +63,107 @@ py.test.raises(TypeError, """D = Class("test2", C, {"a": (Signed, 3)})""") def test_simple_function(): - F = Func([Signed, Signed], Signed) - def f_(a, b): + F = Func([Signed, Signed], Signed) + def f_(a, b): return a+b - f = func(F, _name="f", _callable=f_) - assert typeOf(f) == F + f = func(F, _name="f", _callable=f_) + assert typeOf(f) == F - result = f(2, 3) - assert typeOf(result) == Signed - assert result == 5 + result = f(2, 3) + assert typeOf(result) == Signed + assert result == 5 def test_function_args(): - F = Func([Signed, Signed], Signed) - def f_(a, b): + F = Func([Signed, Signed], Signed) + def f_(a, b): return a+b - f = func(F, _name="f", _callable=f_) + f = func(F, _name="f", _callable=f_) - py.test.raises(TypeError, "f(2.0, 3.0)") - py.test.raises(TypeError, "f()") - py.test.raises(TypeError, "f(1, 2, 3)") + py.test.raises(TypeError, "f(2.0, 3.0)") + py.test.raises(TypeError, "f()") + py.test.raises(TypeError, "f(1, 2, 3)") def test_class_method(): - M = Meth([Signed], Signed) - def m_(self, b): + M = Meth([Signed], Signed) + def m_(self, b): return self.a + b - m = meth(M, _name="m", _callable=m_) - - C = Class("test", None, {"a": (Signed, 2)}, {"m": m}) - c = new(C) - - assert c.m(3) == 5 - - py.test.raises(TypeError, "c.m(3.0)") - py.test.raises(TypeError, "c.m()") - py.test.raises(TypeError, "c.m(1, 2, 3)") + m = meth(M, _name="m", _callable=m_) + + C = Class("test", None, {"a": (Signed, 2)}, {"m": m}) + c = new(C) + + assert c.m(3) == 5 + + py.test.raises(TypeError, "c.m(3.0)") + py.test.raises(TypeError, "c.m()") + py.test.raises(TypeError, "c.m(1, 2, 3)") def test_class_method_field_clash(): - M = Meth([Signed], Signed) - def m_(self, b): + M = Meth([Signed], Signed) + def m_(self, b): return self.a + b - m = meth(M, _name="m", _callable=m_) - - py.test.raises(TypeError, """Class("test", None, {"a": M})""") + m = meth(M, _name="m", _callable=m_) + + py.test.raises(TypeError, """Class("test", None, {"a": M})""") + + py.test.raises(TypeError, """Class("test", None, {"m": Signed}, {"m":m})""") + +def test_simple_recursive_meth(): + C = Class("test", None, {"a": (Signed, 3)}) + + M = Meth([C], Signed) + def m_(self, other): + return self.a + other.a + m = meth(M, _name="m", _callable=m_) + + addMethods(C, {"m": m}) + c = new(C) + + assert c.m(c) == 6 + +def test_explicit_name_clash(): + C = Class("test", None, {}) + + addFields(C, {"a": (Signed, 3)}) + + M = Meth([Signed], Signed) + m = meth(M, _name="m") + + py.test.raises(TypeError, """addMethods(C, {"a": m})""") + + addMethods(C, {"b": m}) + + py.test.raises(TypeError, """addFields(C, {"b": Signed})""") + +def test_instanceof(): + C = Class("test", None, {}) + D = Class("test2", C, {}) + c = new(C) + d = new(D) + assert instanceof(c, C) + assert instanceof(d, D) + assert not instanceof(c, D) + assert instanceof(d, C) + +def test_superclass_meth_lookup(): + C = Class("test", None, {"a": (Signed, 3)}) + + M = Meth([C], Signed) + def m_(self, other): + return self.a + other.a + m = meth(M, _name="m", _callable=m_) + + addMethods(C, {"m": m}) + + D = Class("test2", C, {}) + d = new(D) + + assert d.m(d) == 6 + + def m_(self, other): + return self.a * other.a + m = meth(M, _name="m", _callable=m_) + addMethods(D, {"m": m}) - py.test.raises(TypeError, """Class("test", None, {"m": Signed}, {"m":m})""") + d = new(D) + assert d.m(d) == 9 From mwh at codespeak.net Tue Oct 11 15:57:05 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 15:57:05 +0200 (CEST) Subject: [pypy-svn] r18403 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051011135705.6964C27B74@code1.codespeak.net> Author: mwh Date: Tue Oct 11 15:57:04 2005 New Revision: 18403 Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Log: Another mnemonic (inslwi). Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Tue Oct 11 15:57:04 2005 @@ -508,6 +508,9 @@ def slwi(self, rA, rS, n): self.rlwinm(rA, rS, n, 0, 31-n) + def inslwi(self, rA, rS, n, b): + self.rwlimi(rA, rS, 32-b, b, b + n -1) + # F.5 Simplified Mnemonics for Branch Instructions # there's a lot of these! From mwh at codespeak.net Tue Oct 11 15:58:48 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 15:58:48 +0200 (CEST) Subject: [pypy-svn] r18404 - in pypy/dist/pypy/translator/asm: . test Message-ID: <20051011135848.A769527B75@code1.codespeak.net> Author: mwh Date: Tue Oct 11 15:58:46 2005 New Revision: 18404 Added: pypy/dist/pypy/translator/asm/infregmachine.py Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: (mwh, andrewt) Get back to actually producing some machine code. Slightly less than before, but certainly no more complete. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 11 15:58:46 2005 @@ -40,9 +40,10 @@ g = FuncGenerator(graph) g.gencode() - g.assembler.dump() - return lambda x,y:1#make_func(g.assembler, 'i', 'ii') +# g.assembler.dump() + finreg = g.assembler.allocate_registers(30) + return make_func(finreg.assemble(), 'i', 'ii') class FuncGenerator(object): @@ -117,7 +118,7 @@ if len(block.exits) == 2: assert block.exitswitch is not None - truelink, falselink = block.exits + falselink, truelink = block.exits lastop = block.operations[-1] assert lastop.opname in ['int_gt', 'int_lt', 'int_ge'] A.emit(lastop.opname, *map(self.reg, lastop.args)) Added: pypy/dist/pypy/translator/asm/infregmachine.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/infregmachine.py Tue Oct 11 15:58:46 2005 @@ -0,0 +1,103 @@ + +class Instruction(object): + + def __init__(self, name, arguments): + self.name = name + self.arguments = arguments + + def registers_used(self): + if self.name == 'LIA' or self.name == 'LOAD': + return [self.arguments[0]] + elif self.name in ('JT', 'JF', 'J'): + return [] + else: + return list(self.arguments) + + def __repr__(self): + if self.name == 'LIA': + r, a = self.arguments + args = 'r%s, %s'%tuple(self.arguments) + elif self.name in ('JT', 'JF', 'J'): + args = self.arguments[0] + elif self.name == 'LOAD': + args = 'r%s, %s'%tuple(self.arguments) + else: + args = ', '.join(['r%s'%a for a in self.arguments]) + return ' %-10s %s'%(self.name, args) + +class Assembler(object): + def __init__(self): + self.instructions = [] + + def emit(self, name, *args): + self.instructions.append(Instruction(name, args)) + + def label(self, lab): + self.instructions.append(lab) + + def dump(self): + for i in self.instructions: + if isinstance(i, str): + i += ':' + print i + + def allocate_registers(self, nregisters): + r = FiniteRegisterAssembler(nregisters) + for i in self.instructions: + if not isinstance(i, str): # labels + assert max(i.registers_used() + [0]) < nregisters + r.instructions.append(i) + return r + +class FiniteRegisterAssembler(Assembler): + def __init__(self, nregisters): + Assembler.__init__(self) + self.nregisters = nregisters + + def assemble(self): + from pypy.translator.asm.ppcgen import ppc_assembler + A = ppc_assembler.PPCAssembler() + + for i in self.instructions: + if isinstance(i, str): + A.label(i) + continue + + getattr(self, i.name)(A, *i.arguments) + + return A + + def LIA(self, A, dest, argindex): + assert dest + 2 == argindex + 3 + + def LOAD(self, A, dest, value): + assert isinstance(value, int) + assert -30000 < value < 30000 + A.li(dest + 2, value) + + def int_add(self, A, dest, a, b): + A.add(dest + 2, a + 2, b + 2) + + def int_gt(self, A, a, b): + A.cmpw(a + 2, b + 2) + A.mfcr(0) + # copy bit 1 ('gt') of register 0 to bit 0 of register 0 ('lt') + A.rlwimi(0, 0, 1, 0, 0) + A.mtcr(0) + + def JT(self, A, branch): + # should be "A.bt(BI=0, BD=branch)" but this crashes. + A.blt(branch) + + def J(self, A, branch): + A.b(branch) + + def int_sub(self, A, dest, a, b): + A.sub(dest + 2, a + 2, b + 2) + + def RETPYTHON(self, A, reg): + A.mr(3, reg + 2) + A.blr() + + def MOV(self, A, dest, src): + A.mr(dest + 2, src + 2) Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Tue Oct 11 15:58:46 2005 @@ -5,7 +5,6 @@ class TestAsm(object): def setup_class(cls): - py.test.skip('broken broken broken') if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': py.test.skip('asm generation only on PPC') @@ -38,7 +37,7 @@ def test_int_add(self): def testfn(x=int, y=int): - z = 666 + x + z = 1 + x if z > 0: return x + y + z else: From mwh at codespeak.net Tue Oct 11 16:19:05 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 16:19:05 +0200 (CEST) Subject: [pypy-svn] r18405 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051011141905.336E127B5E@code1.codespeak.net> Author: mwh Date: Tue Oct 11 16:19:03 2005 New Revision: 18405 Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Log: tyop: cmove -> crmove Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Tue Oct 11 16:19:03 2005 @@ -692,7 +692,7 @@ crset = BA.creqv(crbA="crbD", crbB="crbD") crclr = BA.crxor(crbA="crbD", crbB="crbD") - cmove = BA.cror(crbA="crbB") + crmove = BA.cror(crbA="crbB") crnot = BA.crnor(crbA="crbB") # F.7 Simplified Mnemonics for Trap Instructions From mwh at codespeak.net Tue Oct 11 16:26:44 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 16:26:44 +0200 (CEST) Subject: [pypy-svn] r18407 - in pypy/dist/pypy/translator/asm: . test Message-ID: <20051011142644.D574527B75@code1.codespeak.net> Author: mwh Date: Tue Oct 11 16:26:42 2005 New Revision: 18407 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/infregmachine.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: (mwh, andrewt) A new test (a loop!) and associated fixes that turned out to be required: - check number and type of input and output arguments - integer multiplication, less than calculation - less wasteful condition register bit manipulation - allow passing of constants across links. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 11 16:26:42 2005 @@ -1,6 +1,7 @@ import sys, os from pypy.objspace.flow.model import traverse, Block, Variable, Constant from pypy.translator.asm import infregmachine +from pypy.rpython.lltype import Signed #Available Machine code targets (processor+operating system) TARGET_UNKNOWN=0 @@ -38,12 +39,19 @@ graph = translator.getflowgraph(f) + retvar = graph.returnblock.inputargs[0] + + assert retvar.concretetype is Signed + + for v in graph.startblock.inputargs: + assert v.concretetype is Signed + g = FuncGenerator(graph) g.gencode() # g.assembler.dump() finreg = g.assembler.allocate_registers(30) - return make_func(finreg.assemble(), 'i', 'ii') + return make_func(finreg.assemble(), 'i', 'i'*len(graph.startblock.inputargs)) class FuncGenerator(object): @@ -97,7 +105,7 @@ def genlinkcode(self, link): A = self.assembler for s, t in zip(link.args, link.target.inputargs): - if s.name != t.name: + if isinstance(s, Constant) or s.name != t.name: A.emit('MOV', self.reg(t), self.reg(s)) A.emit('J', self.blocktarget(link.target)) Modified: pypy/dist/pypy/translator/asm/infregmachine.py ============================================================================== --- pypy/dist/pypy/translator/asm/infregmachine.py (original) +++ pypy/dist/pypy/translator/asm/infregmachine.py Tue Oct 11 16:26:42 2005 @@ -78,12 +78,18 @@ def int_add(self, A, dest, a, b): A.add(dest + 2, a + 2, b + 2) + def int_sub(self, A, dest, a, b): + A.sub(dest + 2, a + 2, b + 2) + + def int_mul(self, A, dest, a, b): + A.mullw(dest + 2, a + 2, b + 2) + def int_gt(self, A, a, b): A.cmpw(a + 2, b + 2) - A.mfcr(0) - # copy bit 1 ('gt') of register 0 to bit 0 of register 0 ('lt') - A.rlwimi(0, 0, 1, 0, 0) - A.mtcr(0) + A.crmove(0, 1) + + def int_lt(self, A, a, b): + A.cmpw(a + 2, b + 2) def JT(self, A, branch): # should be "A.bt(BI=0, BD=branch)" but this crashes. @@ -92,9 +98,6 @@ def J(self, A, branch): A.b(branch) - def int_sub(self, A, dest, a, b): - A.sub(dest + 2, a + 2, b + 2) - def RETPYTHON(self, A, reg): A.mr(3, reg + 2) A.blr() Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Tue Oct 11 16:26:42 2005 @@ -46,3 +46,19 @@ assert f(2, 3) == testfn(2, 3) assert f(-2, 3) == testfn(-2, 3) + + def test_loop(self): + def testfn(lim=int): + r = 0 + i = 0 + while i < lim: + r += i*i + i += 1 + return r + f = self.getcompiled(testfn)#, view=True) + + assert f(0) == testfn(0) + assert f(10) == testfn(10) + assert f(100) == testfn(100) + assert f(1000) == testfn(1000) + From afa at codespeak.net Tue Oct 11 16:45:16 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 11 Oct 2005 16:45:16 +0200 (CEST) Subject: [pypy-svn] r18409 - pypy/dist/pypy/translator/c/test Message-ID: <20051011144516.BD57327B74@code1.codespeak.net> Author: afa Date: Tue Oct 11 16:45:15 2005 New Revision: 18409 Modified: pypy/dist/pypy/translator/c/test/test_standalone.py Log: (valentino, afa): factor some test functions Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 16:45:15 2005 @@ -39,11 +39,35 @@ res = stack_frames_depth() g2(g1) return res - def entry_point(argv): + + def fn(): count0 = f(0) count10 = f(10) - diff = count10 - count0 - os.write(1, str(diff)+"\n") + return count10 - count0 + + data = wrap_stackless_function(fn) + assert data.strip() == '10' + +def INPROGRESStest_stack_withptr(): + def f(n): + if n > 0: + res = f(n-1) + else: + res = stack_frames_depth(), 1 + return res + + def fn(): + count0, _ = f(0) + count10, _ = f(10) + return count10 - count0 + + data = wrap_stackless_function(fn) + assert data.strip() == '10' + + +def wrap_stackless_function(fn): + def entry_point(argv): + os.write(1, str(fn())+"\n") return 0 t = Translator(entry_point) @@ -54,5 +78,4 @@ cbuilder.stackless = True cbuilder.generate_source() cbuilder.compile() - data = cbuilder.cmdexec('') - assert data.strip() == '10' + return cbuilder.cmdexec('') From afa at codespeak.net Tue Oct 11 16:54:36 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 11 Oct 2005 16:54:36 +0200 (CEST) Subject: [pypy-svn] r18410 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051011145436.9911627B5E@code1.codespeak.net> Author: afa Date: Tue Oct 11 16:54:34 2005 New Revision: 18410 Modified: pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/test/test_standalone.py Log: (Valentino, afa): more stackless tests and bugfixes Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 16:54:34 2005 @@ -166,6 +166,7 @@ argtypes = [erase_ptr_type(v.concretetype) for v in self.graph.getargs()] argtypes = [T for T in argtypes if T is not lltype.Void] + import sys rettype = erase_ptr_type(self.graph.getreturnvar().concretetype) FUNC = lltype.FuncType(argtypes, rettype) slpdata.registerunwindable(self.functionname, FUNC, @@ -180,24 +181,11 @@ curpos = block.operations.index(op) # XXX obscure: find all variables that are produced before 'op' - # and still used by or after 'op'. - produced = {} + vars = [] for v in block.inputargs: - produced[v] = True + vars.append(v) for op1 in block.operations[:curpos]: - produced[op1.result] = True - consumed = {} - for op1 in block.operations[curpos:]: - for v in op1.args: - if isinstance(v, Variable): - consumed[v] = True - if isinstance(block.exitswitch, Variable): - consumed[block.exitswitch] = True - for link in block.exits: - for v in link.args: - if isinstance(v, Variable): - consumed[v] = True - vars = [v for v in produced if v in consumed] + vars.append(op1.result) # get the simplified frame struct that can store these vars counts = {"long": [], @@ -205,7 +193,7 @@ "void*": []} variables_to_restore = [] for v in vars: - st = simplified_type(v.concretetype) + st = simplified_type(erase_ptr_type(v.concretetype)) if st is not None: # ignore the Voids varname = self.expr(v) # XXX hackish: the name of the field in the structure is @@ -250,7 +238,7 @@ varname, cdecl(vartype, ''), structname, fieldname)) retvarname = self.expr(op.result) retvartype = self.lltypename(op.result) - retvarst = simplified_type(op.result.concretetype) + retvarst = simplified_type(erase_ptr_type(op.result.concretetype)) if retvarst is not None: globalretvalvarname = RETVALVARS[retvarst] lines.append('%s = (%s) %s;' % ( @@ -283,10 +271,10 @@ return None elif T is lltype.Float: return "double" + elif T is Address: + return "void*" elif isinstance(T, lltype.Primitive): return "long" # large enough for all other primitives - elif isinstance(T, lltype.Ptr): - return "void*" else: raise Exception("don't know about %r" % (T,)) Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 16:54:34 2005 @@ -48,7 +48,7 @@ data = wrap_stackless_function(fn) assert data.strip() == '10' -def INPROGRESStest_stack_withptr(): +def test_stack_withptr(): def f(n): if n > 0: res = f(n-1) From ac at codespeak.net Tue Oct 11 16:59:54 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Tue, 11 Oct 2005 16:59:54 +0200 (CEST) Subject: [pypy-svn] r18411 - pypy/branch/hl-backend Message-ID: <20051011145954.EB4A727B5E@code1.codespeak.net> Author: ac Date: Tue Oct 11 16:59:54 2005 New Revision: 18411 Added: pypy/branch/hl-backend/ - copied from r18410, pypy/dist/ Log: Branch for development of high-level backends. From adim at codespeak.net Tue Oct 11 17:01:52 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Tue, 11 Oct 2005 17:01:52 +0200 (CEST) Subject: [pypy-svn] r18412 - in pypy/dist/pypy: rpython rpython/module translator/c translator/c/src translator/c/test Message-ID: <20051011150152.C6B5527B5D@code1.codespeak.net> Author: adim Date: Tue Oct 11 17:01:49 2005 New Revision: 18412 Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_stackless.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/test/test_standalone.py Log: provided a simple implementation of stack_too_big() Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Tue Oct 11 17:01:49 2005 @@ -209,6 +209,7 @@ # stackless from pypy.rpython import objectmodel declare(objectmodel.stack_frames_depth, int, 'll_stackless/stack_frames_depth') +declare(objectmodel.stack_too_big, bool, 'll_stackless/stack_too_big') # ___________________________________________________________ # the exceptions that can be implicitely raised by some operations Modified: pypy/dist/pypy/rpython/module/ll_stackless.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_stackless.py (original) +++ pypy/dist/pypy/rpython/module/ll_stackless.py Tue Oct 11 17:01:49 2005 @@ -4,3 +4,7 @@ def ll_stackless_stack_frames_depth(): return objectmodel.stack_frames_depth() ll_stackless_stack_frames_depth.suggested_primitive = True + +def ll_stackless_stack_too_big(): + return objectmodel.stack_too_big() +ll_stackless_stack_too_big.suggested_primitive = True Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Tue Oct 11 17:01:49 2005 @@ -41,6 +41,9 @@ def stack_frames_depth(): return len(inspect.stack()) +def stack_too_big(): + return False + # ____________________________________________________________ Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Oct 11 17:01:49 2005 @@ -50,6 +50,7 @@ ll_thread.ll_thread_start: 'LL_thread_start', ll_thread.ll_thread_get_ident: 'LL_thread_get_ident', ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', + ll_stackless.ll_stackless_stack_too_big: 'LL_stackless_stack_too_big', } #______________________________________________________ Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 17:01:49 2005 @@ -5,6 +5,10 @@ # error "Stackless support: only for stand-alone executables" #endif +#ifndef MAX_STACK_SIZE +#define MAX_STACK_SIZE (1 << 20) +#endif + #define STANDALONE_ENTRY_POINT slp_standalone_entry_point @@ -28,10 +32,12 @@ extern long slp_retval_long; extern double slp_retval_double; extern void *slp_retval_voidptr; +extern char *slp_base_stack_pointer; slp_frame_t* slp_new_frame(int size, int state); long LL_stackless_stack_frames_depth(void); void slp_main_loop(void); +char LL_stackless_stack_too_big(void); #ifndef PYPY_NOT_MAIN_FILE @@ -43,6 +49,7 @@ long slp_retval_long; double slp_retval_double; void *slp_retval_voidptr; +char *slp_base_stack_pointer = NULL; slp_frame_t* slp_new_frame(int size, int state) { @@ -80,6 +87,19 @@ } } +char LL_stackless_stack_too_big(void) +{ + char local; + long result; + /* compute the difference between local variable and + * and a stack origin pointer + */ + result = &local - slp_base_stack_pointer; + if (-MAX_STACK_SIZE < result && result < MAX_STACK_SIZE){ + return 0; + } + return 1; +} #include "slp_state_decoding.h" @@ -132,7 +152,10 @@ int slp_standalone_entry_point(RPyListOfString *argv) { - int result = PYPY_STANDALONE(argv); + char local; + int result; + slp_base_stack_pointer = &local; + result = PYPY_STANDALONE(argv); if (slp_frame_stack_bottom) { slp_main_loop(); result = (int) slp_retval_long; Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 17:01:49 2005 @@ -2,7 +2,7 @@ from pypy.translator.tool.cbuild import build_executable from pypy.annotation.model import SomeList, SomeString from pypy.annotation.listdef import ListDef -from pypy.rpython.objectmodel import stack_frames_depth +from pypy.rpython.objectmodel import stack_frames_depth, stack_too_big import os @@ -65,6 +65,19 @@ assert data.strip() == '10' +def test_stack_too_big(): + def f(n): + if stack_too_big(): + return n + return f(n+1) + + def fn(): + return f(0) + data = wrap_stackless_function(fn) + assert int(data.strip()) > 500 + + + def wrap_stackless_function(fn): def entry_point(argv): os.write(1, str(fn())+"\n") From afa at codespeak.net Tue Oct 11 17:13:36 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 11 Oct 2005 17:13:36 +0200 (CEST) Subject: [pypy-svn] r18413 - pypy/dist/pypy/translator/c/test Message-ID: <20051011151336.CE2D227B5D@code1.codespeak.net> Author: afa Date: Tue Oct 11 17:13:35 2005 New Revision: 18413 Modified: pypy/dist/pypy/translator/c/test/test_standalone.py Log: (valentino, afa): stackless: more tests Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 17:13:35 2005 @@ -64,6 +64,39 @@ data = wrap_stackless_function(fn) assert data.strip() == '10' +def test_stackless_manytimes(): + def f(n): + if n > 0: + stack_frames_depth() + res = f(n-1) + else: + res = stack_frames_depth(), 1 + return res + + def fn(): + count0, _ = f(0) + count10, _ = f(100) + return count10 - count0 + + data = wrap_stackless_function(fn) + assert data.strip() == '100' + +def test_stackless_arguments(): + def f(n, d, t): + if n > 0: + res = f(n-1, d, t) + else: + res = stack_frames_depth(), d, t + return res + + def fn(): + count0, d, t = f(0, 5.5, (1, 2)) + count10, d, t = f(10, 5.5, (1, 2)) + return "[" + str(count10 - count0) + ", " + str(d) + ", " + str(t[0]) + ", " + str(t[1]) + "]" + + data = wrap_stackless_function(fn) + assert eval(data) == [10, 5.500000, 1, 2] + def test_stack_too_big(): def f(n): From ale at codespeak.net Tue Oct 11 17:14:54 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 11 Oct 2005 17:14:54 +0200 (CEST) Subject: [pypy-svn] r18414 - in pypy/dist/pypy/rpython: . module Message-ID: <20051011151454.D18F127B5D@code1.codespeak.net> Author: ale Date: Tue Oct 11 17:14:51 2005 New Revision: 18414 Modified: pypy/dist/pypy/rpython/module/ll_stackless.py pypy/dist/pypy/rpython/objectmodel.py Log: stack_unwind function Modified: pypy/dist/pypy/rpython/module/ll_stackless.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_stackless.py (original) +++ pypy/dist/pypy/rpython/module/ll_stackless.py Tue Oct 11 17:14:51 2005 @@ -1,6 +1,10 @@ from pypy.rpython import objectmodel +def ll_stackless_stack_unwind(): + pass +ll_stackless_stack_unwind.suggested_primitive = True + def ll_stackless_stack_frames_depth(): return objectmodel.stack_frames_depth() ll_stackless_stack_frames_depth.suggested_primitive = True Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Tue Oct 11 17:14:51 2005 @@ -38,9 +38,11 @@ def hlinvoke(repr, llcallable, *args): raise TypeError, "hlinvoke is meant to be rtyped and not called direclty" +def stack_unwind(): + pass + def stack_frames_depth(): return len(inspect.stack()) - def stack_too_big(): return False From bert at codespeak.net Tue Oct 11 17:18:00 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Tue, 11 Oct 2005 17:18:00 +0200 (CEST) Subject: [pypy-svn] r18415 - in pypy/branch/hl-backend/pypy/translator/squeak: . test Message-ID: <20051011151800.A26EF27B5D@code1.codespeak.net> Author: bert Date: Tue Oct 11 17:18:00 2005 New Revision: 18415 Added: pypy/branch/hl-backend/pypy/translator/squeak/ (props changed) pypy/branch/hl-backend/pypy/translator/squeak/__init__.py (contents, props changed) pypy/branch/hl-backend/pypy/translator/squeak/gensqueak.py (contents, props changed) pypy/branch/hl-backend/pypy/translator/squeak/test/ (props changed) pypy/branch/hl-backend/pypy/translator/squeak/test/__init__.py (contents, props changed) pypy/branch/hl-backend/pypy/translator/squeak/test/test_squeaktrans.py (contents, props changed) Log: Initial check-in of Smalltalk code generator Added: pypy/branch/hl-backend/pypy/translator/squeak/__init__.py ============================================================================== Added: pypy/branch/hl-backend/pypy/translator/squeak/gensqueak.py ============================================================================== --- (empty file) +++ pypy/branch/hl-backend/pypy/translator/squeak/gensqueak.py Tue Oct 11 17:18:00 2005 @@ -0,0 +1,272 @@ +import sys +from pypy.objspace.flow.model import traverse +from pypy.objspace.flow import FlowObjSpace +from pypy.objspace.flow.model import Constant, Variable, Block +from pypy.objspace.flow.model import last_exception, checkgraph +from pypy.translator.unsimplify import remove_direct_loops +from pypy.translator.simplify import simplify_graph + +selectormap = { + 'setitem:with:': 'at:put:', + 'getitem:': 'at:', +} + +def camel_case(str): + words = str.split('_') + for i in range(1, len(words)): + words[i] = words[i].capitalize() + return ''.join(words) + +def arg_names(func, names = None): + #XXX need to handle more args, see + # http://docs.python.org/ref/types.html#l2h-139 + co = func.func_code + if not names: + names = co.co_varnames + return names[:co.co_argcount] + +def selector(name, args): + s = name + if args: + s += '_' + for arg in args: + s += arg + ':' + return camel_case(s) + +def signature(sel, args): + if (':' in sel): + parts = [] + names = sel.split(':') + while args: + parts.append(names.pop(0) + ': ' + args.pop(0)) + return ' '.join(parts) + else: + return sel + + +class LoopFinder: + def __init__(self, startblock): + self.loops = {} + self.parents = {startblock: startblock} + self.temps = {} + self.seen = [] + self.visit_Block(startblock) + def visit_Block(self, block, switches=[]): + #self.temps.has_key() + self.seen.append(block) + if block.exitswitch: + switches.append(block) + self.parents[block] = block + for link in block.exits: + self.visit_Link(link, switches) + def visit_Link(self, link, switches): + if link.target in switches: + self.loops[link.target] = True + if not link.target in self.seen: + self.parents[link.target] = self.parents[link.prevblock] + self.visit_Block(link.target, switches) + +class GenSqueak: + + def __init__(self, sqdir, translator, modname=None): + self.sqdir = sqdir + self.translator = translator + self.modname = (modname or + translator.functions[0].__name__) + self.sqnames = { + Constant(None).key: 'nil', + Constant(False).key: 'false', + Constant(True).key: 'true', + } + self.seennames = {} + self.pendingfunctions = [] + self.methods = [] + + t = self.translator + func = t.functions[0] + graph = t.getflowgraph(func) + simplify_graph(graph) + remove_direct_loops(t, graph) + checkgraph(graph) + #self.translator.view() + + self.nameof(func) #add to pending + file = self.sqdir.join('%s.st' % func.__name__).open('w') + self.gen_source(file) + file.close() + #self.translator.view() + + + def gen_source(self, file): + while self.pendingfunctions: + func = self.pendingfunctions.pop() + self.gen_sqfunction(func, file) + + def gen_sqfunction(self, func, f): + + def expr(v): + if isinstance(v, Variable): + return camel_case(v.name) + elif isinstance(v, Constant): + return self.nameof(v.value) + else: + raise TypeError, "expr(%r)" % (v,) + + def oper(op): + args = [expr(arg) for arg in op.args] + name = 'py_'+op.opname + receiver = args[0] + args = args[1:] + argnames = ['with'] * len(args) + if argnames: + argnames[0] = '' + sel = selector(name, argnames) + try: + sel = selectormap[sel] + except KeyError: + pass + return "%s := %s %s." % (expr(op.result), receiver, signature(sel, args)) + + def render_return(args): + if len(args) == 2: + # exception + exc_cls = expr(args[0]) + exc_val = expr(args[1]) + yield "(PyOperationError class: %s value: %s) signal." % (exc_cls, exc_val) + else: + # regular return block + retval = expr(args[0]) + yield "^%s" % retval + + def render_link(link): + block = link.target +# if len(block.exits) == 0: +# #short-cut return block +# for line in render_return(link.args): +# yield line +# return + if link.args: +# yield '| %s |' % repr(block.inputargs[0]) + for i in range(len(link.args)): + yield '%s := %s.' % (expr(block.inputargs[i]), expr(link.args[i])) + for line in render_block(block): + yield line + + def render_block(block): + #yield '"%s"' % repr(block) +# temps = [] +# for op in block.operations: +# if isinstance(op.result, Variable): +# temps.append(expr(op.result)) +# if temps: +# yield "| %s | " % ' '.join(temps) + if loops.has_key(block): + if not loops[block]: + yield '"skip1"' + return + yield "[" + for op in block.operations: + yield "%s" % oper(op) + if len(block.exits) == 0: + for line in render_return(block.inputargs): + yield line + return + elif block.exitswitch is None: + # single-exit block + assert len(block.exits) == 1 + for line in render_link(block.exits[0]): + yield line + else: + #exitswitch + if loops.has_key(block): + if loops[block]: + loops[block] = False + yield "%s] whileTrue: [" % expr(block.exitswitch) + for line in render_link(block.exits[True]): + yield " %s" % line + yield "]." + for line in render_link(block.exits[False]): + yield "%s" % line + else: + yield "%s ifTrue: [" % expr(block.exitswitch) + for line in render_link(block.exits[True]): + yield " %s" % line + yield "] ifFalse: [" + for line in render_link(block.exits[False]): + yield " %s" % line + yield "]" + + t = self.translator + graph = t.getflowgraph(func) + + start = graph.startblock + args = [expr(arg) for arg in start.inputargs] + print >> f, '%s' % signature(self.nameof(func), args) + + loops = LoopFinder(start).loops + + for line in render_block(start): + print >> f, ' %s' % line + print >> f + + def nameof(self, obj): + key = Constant(obj).key + try: + return self.sqnames[key] + except KeyError: + if (type(obj).__module__ != '__builtin__' and + not isinstance(obj, type)): # skip user-defined metaclasses + # assume it's a user defined thingy + name = self.nameof_instance(obj) + else: + for cls in type(obj).__mro__: + meth = getattr(self, + 'nameof_' + cls.__name__.replace(' ', ''), + None) + if meth: + break + else: + types = ['nameof_'+t.__name__ for t in type(obj).mro()] + raise Exception, "nameof(%r): no method %s" % (obj, types) + name = meth(obj) + self.sqnames[key] = name + return name + + def nameof_int(self, i): + return str(i) + + def nameof_function(self, func): + printable_name = '(%s:%d) %s' % ( + func.func_globals.get('__name__', '?'), + func.func_code.co_firstlineno, + func.__name__) + if self.translator.frozen: + if func not in self.translator.flowgraphs: + print "NOT GENERATING", printable_name + return self.skipped_function(func) + else: + if (func.func_doc and + func.func_doc.lstrip().startswith('NOT_RPYTHON')): + print "skipped", printable_name + return self.skipped_function(func) + name = self.unique_name(func.__name__) + args = arg_names(func) + sel = selector(name, args) + self.pendingfunctions.append(func) + return sel + + + def unique_name(self, basename): + n = self.seennames.get(basename, 0) + self.seennames[basename] = n+1 + if n == 0: + return basename + else: + return self.unique_name('%s_%d' % (basename, n)) + + + def skipped_function(self, func): + # debugging only! Generates a placeholder for missing functions + # that raises an exception when called. + name = self.unique_name(camel_case('skipped_' + func.__name__)) + return name Added: pypy/branch/hl-backend/pypy/translator/squeak/test/__init__.py ============================================================================== Added: pypy/branch/hl-backend/pypy/translator/squeak/test/test_squeaktrans.py ============================================================================== --- (empty file) +++ pypy/branch/hl-backend/pypy/translator/squeak/test/test_squeaktrans.py Tue Oct 11 17:18:00 2005 @@ -0,0 +1,35 @@ +from pypy.tool.udir import udir +from pypy.translator.test import snippet +from pypy.translator.squeak.gensqueak import GenSqueak +from pypy.translator.translator import Translator + + +def looping(i = (int), j = (int)): + while i > 0: + i -= 1 + while j > 0: + j -= 1 + +class TestSqueakTrans: + + def build_sqfunc(self, func): + try: func = func.im_func + except AttributeError: pass + t = Translator(func) + t.simplify() + self.gen = GenSqueak(udir, t) + + def test_simple_func(self): + self.build_sqfunc(snippet.simple_func) + + def test_if_then_else(self): + self.build_sqfunc(snippet.if_then_else) + + def test_two_plus_two(self): + self.build_sqfunc(snippet.two_plus_two) + + def test_my_gcd(self): + self.build_sqfunc(snippet.my_gcd) + + def test_looping(self): + self.build_sqfunc(looping) From ale at codespeak.net Tue Oct 11 17:19:53 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 11 Oct 2005 17:19:53 +0200 (CEST) Subject: [pypy-svn] r18416 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20051011151953.8500327B5E@code1.codespeak.net> Author: ale Date: Tue Oct 11 17:19:49 2005 New Revision: 18416 Modified: pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/test/test_standalone.py Log: (tismer, ale) adding the stack_unwind function Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Oct 11 17:19:49 2005 @@ -50,6 +50,7 @@ ll_thread.ll_thread_start: 'LL_thread_start', ll_thread.ll_thread_get_ident: 'LL_thread_get_ident', ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', + ll_stackless.ll_stackless_stack_unwind: 'LL_stackless_stack_unwind', ll_stackless.ll_stackless_stack_too_big: 'LL_stackless_stack_too_big', } Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 17:19:49 2005 @@ -87,6 +87,19 @@ } } +void LL_stackless_stack_unwind(void) +{ + if (slp_frame_stack_top) + goto resume; + + slp_frame_stack_top = slp_frame_stack_bottom = + slp_new_frame(sizeof(slp_frame_t), 0); + return ; + + resume: + slp_frame_stack_top = NULL; +} + char LL_stackless_stack_too_big(void) { char local; @@ -166,3 +179,4 @@ #endif /* PYPY_NOT_MAIN_FILE */ #endif USE_STACKLESS + Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 17:19:49 2005 @@ -21,10 +21,13 @@ self.decode_table = [] # start the decoding table with entries for the functions that # are written manually in ll_stackless.h + + self.registerunwindable('LL_stackless_stack_unwind', + lltype.FuncType([], lltype.Void), + resume_points=1) self.registerunwindable('LL_stackless_stack_frames_depth', lltype.FuncType([], lltype.Signed), resume_points=1) - def registerunwindable(self, functionname, FUNC, resume_points): if resume_points >= 1: try: Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 17:19:49 2005 @@ -2,7 +2,7 @@ from pypy.translator.tool.cbuild import build_executable from pypy.annotation.model import SomeList, SomeString from pypy.annotation.listdef import ListDef -from pypy.rpython.objectmodel import stack_frames_depth, stack_too_big +from pypy.rpython.objectmodel import stack_unwind, stack_frames_depth, stack_too_big import os @@ -26,7 +26,7 @@ assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') -def test_stack_unwind(): +def test_stack_depth(): def g1(): "just to check Void special cases around the code" def g2(ignored): @@ -124,4 +124,21 @@ cbuilder.stackless = True cbuilder.generate_source() cbuilder.compile() + data = cbuilder.cmdexec('') + assert data.strip() == '10' + +def test_stack_unwind(): + def entry_point(argv): + stack_unwind() + 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.stackless = True + cbuilder.generate_source() + cbuilder.compile() + data = cbuilder.cmdexec('') return cbuilder.cmdexec('') From bert at codespeak.net Tue Oct 11 17:38:06 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Tue, 11 Oct 2005 17:38:06 +0200 (CEST) Subject: [pypy-svn] r18418 - in pypy/branch/hl-backend/pypy/rpython/ootype: . test Message-ID: <20051011153806.AEC4F27B5E@code1.codespeak.net> Author: bert Date: Tue Oct 11 17:38:06 2005 New Revision: 18418 Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Log: Refactor to share code with lltype. (Samuele, Bert, Boria, Aurelien, Arre) Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Tue Oct 11 17:38:06 2005 @@ -4,130 +4,11 @@ from pypy.tool.uid import Hashable from pypy.tool.tls import tlsobject from types import NoneType +from pypy.rpython.lltype import LowLevelType, Signed, Unsigned, Float, Char +from pypy.rpython.lltype import Bool, Void, UniChar, typeOf -TLS = tlsobject() - -def saferecursive(func, defl): - def safe(*args): - try: - seeing = TLS.seeing - except AttributeError: - seeing = TLS.seeing = {} - seeingkey = tuple([func] + [id(arg) for arg in args]) - if seeingkey in seeing: - return defl - seeing[seeingkey] = True - try: - return func(*args) - finally: - del seeing[seeingkey] - return safe - -#safe_equal = saferecursive(operator.eq, True) -def safe_equal(x, y): - # a specialized version for performance - try: - seeing = TLS.seeing_eq - except AttributeError: - seeing = TLS.seeing_eq = {} - seeingkey = (id(x), id(y)) - if seeingkey in seeing: - return True - seeing[seeingkey] = True - try: - return x == y - finally: - del seeing[seeingkey] - - -class frozendict(dict): - - def __hash__(self): - items = self.items() - items.sort() - return hash(tuple(items)) - - -class OOType(object): - # the following line prevents '__cached_hash' to be in the __dict__ of - # the instance, which is needed for __eq__() and __hash__() to work. - __slots__ = ['__dict__', '__cached_hash'] - - def __eq__(self, other): - return self.__class__ is other.__class__ and ( - self is other or safe_equal(self.__dict__, other.__dict__)) - - def __ne__(self, other): - return not (self == other) - - def __hash__(self): - # cannot use saferecursive() -- see test_lltype.test_hash(). - # NB. the __cached_hash should neither be used nor updated - # if we enter with hash_level > 0, because the computed - # __hash__ can be different in this situation. - hash_level = 0 - try: - hash_level = TLS.nested_hash_level - if hash_level == 0: - return self.__cached_hash - except AttributeError: - pass - if hash_level >= 3: - return 0 - items = self.__dict__.items() - items.sort() - TLS.nested_hash_level = hash_level + 1 - try: - result = hash((self.__class__,) + tuple(items)) - finally: - TLS.nested_hash_level = hash_level - if hash_level == 0: - self.__cached_hash = result - return result - - # due to this dynamic hash value, we should forbid - # pickling, until we have an algorithm for that. - # but we just provide a tag for external help. - __hash_is_not_constant__ = True - - def __repr__(self): - return '<%s>' % (self,) - - def __str__(self): - return self.__class__.__name__ - - def _short_name(self): - return str(self) - - def _defl(self, parent=None, parentindex=None): - raise NotImplementedError - - def _freeze_(self): - return True - -class Primitive(OOType): - def __init__(self, name, default): - self._name = self.__name__ = name - self._default = default - - def __str__(self): - return self._name - - def _defl(self, parent=None, parentindex=None): - return self._default - - def _is_atomic(self): - return True - - _example = _defl - -Signed = Primitive("Signed", 0) -Unsigned = Primitive("Unsigned", r_uint(0)) -Float = Primitive("Float", 0.0) -Char = Primitive("Char", '\x00') -Bool = Primitive("Bool", False) -Void = Primitive("Void", None) -UniChar = Primitive("UniChar", u'\x00') +class OOType(LowLevelType): + pass class Class(OOType): @@ -205,16 +86,16 @@ return meth -class Func(OOType): +class StaticMethod(OOType): def __init__(self, args, result): self.ARGS = tuple(args) self.RESULT = result -class Meth(Func): +class Meth(StaticMethod): def __init__(self, args, result): - Func.__init__(self, args, result) + StaticMethod.__init__(self, args, result) # ____________________________________________________________ class _instance(object): @@ -282,11 +163,11 @@ raise RuntimeError,"calling undefined function" return callb -class _func(_callable): +class _static_meth(_callable): - def __init__(self, FUNCTION, **attrs): - assert isinstance(FUNCTION, Func) - _callable.__init__(self, FUNCTION, **attrs) + def __init__(self, STATICMETHOD, **attrs): + assert isinstance(STATICMETHOD, StaticMethod) + _callable.__init__(self, STATICMETHOD, **attrs) def __call__(self, *args): return self._checkargs(args)(*args) @@ -312,8 +193,8 @@ def new(CLASS): return _instance(CLASS) -def func(FUNCTION, **attrs): - return _func(FUNCTION, **attrs) +def static_meth(FUNCTION, **attrs): + return _static_meth(FUNCTION, **attrs) def meth(METHOD, **attrs): return _meth(METHOD, **attrs) @@ -336,30 +217,3 @@ return False -def typeOf(val): - try: - return val._TYPE - except AttributeError: - tp = type(val) - if tp is NoneType: - return Void # maybe - if tp is int: - return Signed - if tp is bool: - return Bool - if tp is r_uint: - return Unsigned - if tp is float: - return Float - if tp is str: - assert len(val) == 1 - return Char - if tp is unicode: - assert len(val) == 1 - return UniChar - raise TypeError("typeOf(%r object)" % (tp.__name__,)) - -class InvalidCast(TypeError): - pass - - Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 17:38:06 2005 @@ -62,22 +62,22 @@ py.test.raises(TypeError, """D = Class("test2", C, {"a": (Signed, 3)})""") -def test_simple_function(): - F = Func([Signed, Signed], Signed) +def test_simple_static_method(): + F = StaticMethod([Signed, Signed], Signed) def f_(a, b): return a+b - f = func(F, _name="f", _callable=f_) + f = static_meth(F, _name="f", _callable=f_) assert typeOf(f) == F result = f(2, 3) assert typeOf(result) == Signed assert result == 5 -def test_function_args(): - F = Func([Signed, Signed], Signed) +def test_static_method_args(): + F = StaticMethod([Signed, Signed], Signed) def f_(a, b): return a+b - f = func(F, _name="f", _callable=f_) + f = static_meth(F, _name="f", _callable=f_) py.test.raises(TypeError, "f(2.0, 3.0)") py.test.raises(TypeError, "f()") From ale at codespeak.net Tue Oct 11 18:01:55 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 11 Oct 2005 18:01:55 +0200 (CEST) Subject: [pypy-svn] r18420 - pypy/dist/pypy/translator/c/src Message-ID: <20051011160155.2C97827B74@code1.codespeak.net> Author: ale Date: Tue Oct 11 18:01:53 2005 New Revision: 18420 Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h Log: changed the order of functions Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 18:01:53 2005 @@ -60,6 +60,19 @@ return f; } +void LL_stackless_stack_unwind(void) +{ + if (slp_frame_stack_top) + goto resume; + + slp_frame_stack_top = slp_frame_stack_bottom = + slp_new_frame(sizeof(slp_frame_t), 0); + return ; + + resume: + slp_frame_stack_top = NULL; +} + /* example function for testing */ @@ -69,7 +82,7 @@ goto resume; slp_frame_stack_top = slp_frame_stack_bottom = - slp_new_frame(sizeof(slp_frame_t), 0); + slp_new_frame(sizeof(slp_frame_t), 1); return -1; resume: @@ -87,18 +100,6 @@ } } -void LL_stackless_stack_unwind(void) -{ - if (slp_frame_stack_top) - goto resume; - - slp_frame_stack_top = slp_frame_stack_bottom = - slp_new_frame(sizeof(slp_frame_t), 0); - return ; - - resume: - slp_frame_stack_top = NULL; -} char LL_stackless_stack_too_big(void) { From bert at codespeak.net Tue Oct 11 18:20:07 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Tue, 11 Oct 2005 18:20:07 +0200 (CEST) Subject: [pypy-svn] r18421 - in pypy/branch/hl-backend/pypy/rpython/ootype: . test Message-ID: <20051011162007.CC73927B5D@code1.codespeak.net> Author: bert Date: Tue Oct 11 18:20:07 2005 New Revision: 18421 Added: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Log: Some failing tests. Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Tue Oct 11 18:20:07 2005 @@ -5,7 +5,7 @@ from pypy.tool.tls import tlsobject from types import NoneType from pypy.rpython.lltype import LowLevelType, Signed, Unsigned, Float, Char -from pypy.rpython.lltype import Bool, Void, UniChar, typeOf +from pypy.rpython.lltype import Bool, Void, UniChar, typeOf, Primitive class OOType(LowLevelType): pass Added: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py ============================================================================== --- (empty file) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py Tue Oct 11 18:20:07 2005 @@ -0,0 +1,17 @@ +from pypy.rpython.ootype.ootype import * +from pypy.annotation import model as annmodel +from pypy.objspace.flow import FlowObjSpace +from pypy.translator.annrpython import RPythonAnnotator + + +def test_simple(): + C = Class("test", None, {'a': Signed}) + + def oof(): + c = new(C) + return c.a + + a = RPythonAnnotator() + s = a.build_types(oof, []) + assert s.knowntype == int + Added: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py ============================================================================== --- (empty file) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py Tue Oct 11 18:20:07 2005 @@ -0,0 +1,38 @@ +from pypy.translator.translator import Translator +from pypy.rpython import lltype +from pypy.rpython.ootype import ootype + +def check_only_ootype(graph): + def check_ootype(v): + t = v.concretetype + assert isinstance(t, ootype.Primitive) or isinstance(t, ootype.OOType) + + for block in graph.iterblocks(): + for var in block.getvariables(): + check_ootype(var) + for const in block.getconstants(): + check_ootype(const) + +def test_simple(): + def f(a, b): + return a + b + t = Translator(f) + t.annotate([int, int]) + t.specialize() + + graph = t.flowgraphs[f] + check_only_ootype(graph) + +def test_simple_call(): + def f(a, b): + return a + b + + def g(): + return f(5, 3) + + t = Translator(g) + t.annotate([]) + t.specialize() + + graph = t.flowgraphs[g] + check_only_ootype(graph) From tismer at codespeak.net Tue Oct 11 18:21:48 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 11 Oct 2005 18:21:48 +0200 (CEST) Subject: [pypy-svn] r18422 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051011162148.0F24527B5D@code1.codespeak.net> Author: tismer Date: Tue Oct 11 18:21:46 2005 New Revision: 18422 Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/stackless.py Log: small tweaks Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 18:21:46 2005 @@ -6,7 +6,7 @@ #endif #ifndef MAX_STACK_SIZE -#define MAX_STACK_SIZE (1 << 20) +#define MAX_STACK_SIZE (1 << (20-1)) #endif #define STANDALONE_ENTRY_POINT slp_standalone_entry_point Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 18:21:46 2005 @@ -16,7 +16,7 @@ def __init__(self): self.frame_types = {} - self.globalstatecounter = 1 + self.globalstatecounter = 2 self.allsignatures = {} self.decode_table = [] # start the decoding table with entries for the functions that @@ -81,15 +81,14 @@ saving_lines.append('((struct %s*) f)->%s = %s;' % ( structname, varname, varname)) - head = 'void *save_%(name)s(%(arguments)s);' + head = 'void save_%(name)s(%(arguments)s);' code = str(py.code.Source(''' - void *save_%(name)s(%(arguments)s) + void save_%(name)s(%(arguments)s) { slp_frame_t* f = slp_new_frame(sizeof(struct %(name)s), state); slp_frame_stack_bottom->f_back = f; slp_frame_stack_bottom = f; %(saving_lines)s - return NULL; } ''')) argdict = {'name': structname, @@ -218,13 +217,7 @@ arguments = ['%d' % stacklessdata.globalstatecounter] + vars stacklessdata.globalstatecounter += 1 savecall = 'save_%s(%s);' % (structname, ', '.join(arguments)) - retvar = self.graph.getreturnvar() - if retvar.concretetype is lltype.Void: - savecall += ' return;' - else: - retvartype = self.lltypename(retvar) - savecall = 'return (%s) %s' % (cdecl(retvartype, ''), - savecall) + savecall += ' return %s;' % self.error_return_value() self.savelines.append('%s: %s' % (savelabel, savecall)) # generate the resume block, e.g. From afa at codespeak.net Tue Oct 11 18:25:03 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 11 Oct 2005 18:25:03 +0200 (CEST) Subject: [pypy-svn] r18423 - in pypy/dist/pypy/translator/c: src test Message-ID: <20051011162503.54D8827B5D@code1.codespeak.net> Author: afa Date: Tue Oct 11 18:25:01 2005 New Revision: 18423 Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/test/test_standalone.py Log: (afa, valentino): more on stackless: - reduce MAX_STACK_SIZE on Windows - correct tests Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 18:25:01 2005 @@ -6,7 +6,11 @@ #endif #ifndef MAX_STACK_SIZE -#define MAX_STACK_SIZE (1 << (20-1)) +# ifdef MS_WINDOWS +# define MAX_STACK_SIZE (1 << 19) +# else +# define MAX_STACK_SIZE (1 << 20) +# endif #endif #define STANDALONE_ENTRY_POINT slp_standalone_entry_point Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 18:25:01 2005 @@ -95,7 +95,7 @@ return "[" + str(count10 - count0) + ", " + str(d) + ", " + str(t[0]) + ", " + str(t[1]) + "]" data = wrap_stackless_function(fn) - assert eval(data) == [10, 5.500000, 1, 2] + assert eval(data) == [10, 5.5, 1, 2] def test_stack_too_big(): @@ -125,7 +125,7 @@ cbuilder.generate_source() cbuilder.compile() data = cbuilder.cmdexec('') - assert data.strip() == '10' + return data def test_stack_unwind(): def entry_point(argv): From tismer at codespeak.net Tue Oct 11 18:33:06 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Tue, 11 Oct 2005 18:33:06 +0200 (CEST) Subject: [pypy-svn] r18424 - pypy/dist/pypy/translator/c/src Message-ID: <20051011163306.E7FF227B5D@code1.codespeak.net> Author: tismer Date: Tue Oct 11 18:33:05 2005 New Revision: 18424 Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h Log: kept MAX_STACK_SIZE at 1 << 20, since this is true in most cases. Used a local set to half of it to do the check. Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 18:33:05 2005 @@ -6,11 +6,7 @@ #endif #ifndef MAX_STACK_SIZE -# ifdef MS_WINDOWS -# define MAX_STACK_SIZE (1 << 19) -# else # define MAX_STACK_SIZE (1 << 20) -# endif #endif #define STANDALONE_ENTRY_POINT slp_standalone_entry_point @@ -109,11 +105,12 @@ { char local; long result; + int simple_check = MAX_STACK_SIZE / 2; /* compute the difference between local variable and * and a stack origin pointer */ result = &local - slp_base_stack_pointer; - if (-MAX_STACK_SIZE < result && result < MAX_STACK_SIZE){ + if (-simple_check < result && result < simple_check){ return 0; } return 1; From mwh at codespeak.net Tue Oct 11 18:52:12 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 11 Oct 2005 18:52:12 +0200 (CEST) Subject: [pypy-svn] r18425 - pypy/dist/pypy/translator/asm Message-ID: <20051011165212.2F6A827B5D@code1.codespeak.net> Author: mwh Date: Tue Oct 11 18:52:10 2005 New Revision: 18425 Added: pypy/dist/pypy/translator/asm/regmap.py Log: (andrewt, mwh) register allocation beginnings Added: pypy/dist/pypy/translator/asm/regmap.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/regmap.py Tue Oct 11 18:52:10 2005 @@ -0,0 +1,75 @@ + + +import random +random.seed(101) +n=10 +m=5 +initial=[ random.randint(1,m) for x in range(n)] + +#now recode to n-register machine + +def remap(regs,n): + return regs + +def remap(regs,n): + pipe=[] + old2new={} + re=[] + for reg in regs: + goingin=old2new.get(reg,reg) + + if goingin>n: + goingout=pipe[-1] + re.append((goingin,goingout)) + old2new[goingin]=goingout + old2new[goingout]=goingin + reg=goingout + pipe=[goingin]+pipe + val2append=goingout + else: + val2append=goingin + if val2append not in pipe: + pipe=[val2append]+pipe + if len(pipe)>n: + pipe.pop() + re.append(val2append) + print re + return re + + +def remap(regs,n): + pipe=[] + old2new={} + re=[] + for reg in regs: + goingin=old2new.get(reg,reg) + #print reg,pipe,old2new + if goingin>n: + goingout=pipe[-1] + re.append((goingin,goingout)) + old2new[goingin]=goingout + old2new[goingout]=goingin + val=goingout + else: + val=goingin + pipe=[val]+pipe + re.append(val) + if len(pipe)>n: + pipe.pop() + return re + + +assert remap([1,2,3],3)==[1,2,3] +assert remap([1,2,3],2)==[1,2,(3,1),1] +assert remap([1,2,3,1],2)==[1,2,(3,1),1,(3,2),2] +assert remap([1,2,3,4,2],2)==[1,2,(3,1),1,(4,2),2,(4,1),1] +assert remap([1,2,3,2,1],2)==[1, 2, (3, 1), 1, 2, (3, 1), 1] + +assert remap([1,2,3,4],1)==[1,(2,1),1,(3,1),1,(4,1),1] +assert remap([1,2,3,4,5,4,3,2,1],10)==[1,2,3,4,5,4,3,2,1] +assert remap([1,2,3,4,5,4,3,2,1],3)==[1,2,3,(4,1),1,(5,2),2,1,3,(5,2),2,(4,1),1] + + + + + From afa at codespeak.net Tue Oct 11 18:59:27 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 11 Oct 2005 18:59:27 +0200 (CEST) Subject: [pypy-svn] r18426 - pypy/dist/pypy/translator/c Message-ID: <20051011165927.CA7BA27B5D@code1.codespeak.net> Author: afa Date: Tue Oct 11 18:59:24 2005 New Revision: 18426 Modified: pypy/dist/pypy/translator/c/stackless.py Log: (valentino, afa): stackless: some cleanup Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 18:59:24 2005 @@ -16,18 +16,18 @@ def __init__(self): self.frame_types = {} - self.globalstatecounter = 2 self.allsignatures = {} self.decode_table = [] + # start the decoding table with entries for the functions that # are written manually in ll_stackless.h - self.registerunwindable('LL_stackless_stack_unwind', lltype.FuncType([], lltype.Void), resume_points=1) self.registerunwindable('LL_stackless_stack_frames_depth', lltype.FuncType([], lltype.Signed), resume_points=1) + def registerunwindable(self, functionname, FUNC, resume_points): if resume_points >= 1: try: @@ -214,8 +214,13 @@ # generate the 'save:' line, e.g. # save_0: return (int) save_frame_1(0, (long) n); savelabel = 'save_%d' % len(self.savelines) - arguments = ['%d' % stacklessdata.globalstatecounter] + vars - stacklessdata.globalstatecounter += 1 + + # Find the globally unique number for our state. + # It is the total number of saved states so far + globalstatecounter = len(stacklessdata.decode_table) + len(self.savelines) + + arguments = ['%d' % globalstatecounter] + vars + savecall = 'save_%s(%s);' % (structname, ', '.join(arguments)) savecall += ' return %s;' % self.error_return_value() self.savelines.append('%s: %s' % (savelabel, savecall)) From adim at codespeak.net Tue Oct 11 19:00:51 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Tue, 11 Oct 2005 19:00:51 +0200 (CEST) Subject: [pypy-svn] r18427 - in pypy/dist/pypy: rpython rpython/module translator translator/c/src translator/c/test Message-ID: <20051011170051.4DDB727B5E@code1.codespeak.net> Author: adim Date: Tue Oct 11 19:00:46 2005 New Revision: 18427 Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_stackless.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/test/test_standalone.py pypy/dist/pypy/translator/transform.py Log: (arigo, adim) automatically add stack_unwind() when recursion is detected Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Tue Oct 11 19:00:46 2005 @@ -210,6 +210,7 @@ from pypy.rpython import objectmodel declare(objectmodel.stack_frames_depth, int, 'll_stackless/stack_frames_depth') declare(objectmodel.stack_too_big, bool, 'll_stackless/stack_too_big') +declare(objectmodel.auto_stack_unwind, noneannotation, 'll_stackless/auto_stack_unwind') # ___________________________________________________________ # the exceptions that can be implicitely raised by some operations Modified: pypy/dist/pypy/rpython/module/ll_stackless.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_stackless.py (original) +++ pypy/dist/pypy/rpython/module/ll_stackless.py Tue Oct 11 19:00:46 2005 @@ -12,3 +12,7 @@ def ll_stackless_stack_too_big(): return objectmodel.stack_too_big() ll_stackless_stack_too_big.suggested_primitive = True + +def ll_stackless_auto_stack_unwind(): + if ll_stackless_stack_too_big(): + ll_stackless_stack_unwind() Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Tue Oct 11 19:00:46 2005 @@ -43,9 +43,13 @@ def stack_frames_depth(): return len(inspect.stack()) + def stack_too_big(): return False +def auto_stack_unwind(): + if stack_too_big(): + stack_unwind() # ____________________________________________________________ Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 11 19:00:46 2005 @@ -115,6 +115,7 @@ } return 1; } + #include "slp_state_decoding.h" Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 11 19:00:46 2005 @@ -1,5 +1,6 @@ from pypy.translator.translator import Translator -from pypy.translator.tool.cbuild import build_executable +from pypy.translator.tool.cbuild import build_executable +from pypy.translator.transform import insert_stackcheck from pypy.annotation.model import SomeList, SomeString from pypy.annotation.listdef import ListDef from pypy.rpython.objectmodel import stack_unwind, stack_frames_depth, stack_too_big @@ -111,34 +112,39 @@ -def wrap_stackless_function(fn): +def wrap_stackless_function(fn, stackcheck=False): def entry_point(argv): os.write(1, str(fn())+"\n") return 0 t = Translator(entry_point) s_list_of_strings = SomeList(ListDef(None, SomeString())) - t.annotate([s_list_of_strings]) + ann = t.annotate([s_list_of_strings]) + if stackcheck: + insert_stackcheck(ann) t.specialize() cbuilder = t.cbuilder(standalone=True) cbuilder.stackless = True cbuilder.generate_source() cbuilder.compile() - data = cbuilder.cmdexec('') - return data + return cbuilder.cmdexec('') def test_stack_unwind(): - def entry_point(argv): + def f(): stack_unwind() - return 0 + return 42 - 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.stackless = True - cbuilder.generate_source() - cbuilder.compile() - data = cbuilder.cmdexec('') - return cbuilder.cmdexec('') + data = wrap_stackless_function(f) + assert int(data.strip()) == 42 + + +def test_auto_stack_unwind(): + def f(n): + if n == 1: + return 1 + return (n+f(n-1)) % 1291 + + def fn(): + return f(10**6) + data = wrap_stackless_function(fn, stackcheck=True) + assert int(data.strip()) == 704 Modified: pypy/dist/pypy/translator/transform.py ============================================================================== --- pypy/dist/pypy/translator/transform.py (original) +++ pypy/dist/pypy/translator/transform.py Tue Oct 11 19:00:46 2005 @@ -14,7 +14,7 @@ from pypy.translator.annrpython import CannotSimplify from pypy.annotation import model as annmodel from pypy.annotation.specialize import MemoTable - +from pypy.rpython.objectmodel import auto_stack_unwind def checkgraphs(self, blocks): seen = {} @@ -187,6 +187,30 @@ else: op.opname = intern('call_specialcase') +def insert_stackcheck(ann): + from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles + edges = [] + for callposition, (caller, callee) in ann.translator.callgraph.items(): + edge = Edge(caller, callee) + edge.callposition = callposition + edges.append(edge) + edgedict = make_edge_dict(edges) + for edge in break_cycles(edgedict, edgedict): + caller = edge.source + _, _, call_tag = edge.callposition + if call_tag: + _, caller_block, _ = call_tag + else: + ann.warning("cycle detected but no information on where to insert " + "auto_stack_unwind()") + continue + # caller block found, insert auto_stack_unwind() + v = Variable() + # push annotation on v + ann.setbinding(v, annmodel.SomeImpossibleValue()) + unwind_op = SpaceOperation('simple_call', [Constant(auto_stack_unwind)], v) + caller_block.operations.insert(0, unwind_op) + default_extra_passes = [ transform_specialization, transform_allocate, From bert at codespeak.net Tue Oct 11 19:56:43 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Tue, 11 Oct 2005 19:56:43 +0200 (CEST) Subject: [pypy-svn] r18429 - in pypy/branch/hl-backend/pypy: annotation rpython/ootype rpython/ootype/test Message-ID: <20051011175643.0D51227B57@code1.codespeak.net> Author: bert Date: Tue Oct 11 19:56:37 2005 New Revision: 18429 Modified: pypy/branch/hl-backend/pypy/annotation/builtin.py pypy/branch/hl-backend/pypy/annotation/model.py pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Log: (Bert, Arre) - made Class hashable - introduced SomeRef (subclass of SomePtr for now) - new builtins: new(), instanceof() Modified: pypy/branch/hl-backend/pypy/annotation/builtin.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/builtin.py (original) +++ pypy/branch/hl-backend/pypy/annotation/builtin.py Tue Oct 11 19:56:37 2005 @@ -364,6 +364,24 @@ BUILTIN_ANALYZERS[lltype.getRuntimeTypeInfo] = getRuntimeTypeInfo BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info +# ootype +from pypy.annotation.model import SomeRef +from pypy.rpython.ootype import ootype + +def new(C): + assert C.is_constant() + i = ootype.new(C.const) + r = SomeRef(ootype.typeOf(i)) + return r + +def instanceof(c, C): + assert C.is_constant() + assert isinstance(C.const, ootype.Class) + return SomeBool() + +BUILTIN_ANALYZERS[ootype.instanceof] = instanceof +BUILTIN_ANALYZERS[ootype.new] = new + #________________________________ # non-gc objects Modified: pypy/branch/hl-backend/pypy/annotation/model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/model.py Tue Oct 11 19:56:37 2005 @@ -431,6 +431,9 @@ def can_be_none(self): return False +class SomeRef(SomePtr): + pass + from pypy.rpython import lltype annotation_to_ll_map = [ Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Tue Oct 11 19:56:37 2005 @@ -6,6 +6,7 @@ from types import NoneType from pypy.rpython.lltype import LowLevelType, Signed, Unsigned, Float, Char from pypy.rpython.lltype import Bool, Void, UniChar, typeOf, Primitive +from pypy.rpython.lltype import frozendict class OOType(LowLevelType): pass @@ -15,8 +16,8 @@ def __init__(self, name, superclass, fields, methods={}): self._superclass = superclass - self._methods = {} - self._fields = {} + self._methods = frozendict() + self._fields = frozendict() self._add_fields(fields) self._add_methods(methods) @@ -26,6 +27,9 @@ def _defl(self): return self._null + def _example(self): + return new(self) + def _add_fields(self, fields): for name, defn in fields.iteritems(): if self._lookup(name) is not None: Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py Tue Oct 11 19:56:37 2005 @@ -4,14 +4,28 @@ from pypy.translator.annrpython import RPythonAnnotator -def test_simple(): +def test_simple_new(): C = Class("test", None, {'a': Signed}) - + def oof(): c = new(C) return c.a a = RPythonAnnotator() s = a.build_types(oof, []) + #a.translator.view() + assert s.knowntype == int +def test_simple_instanceof(): + C = Class("test", None, {'a': Signed}) + + def oof(): + c = new(C) + return instanceof(c, C) + + a = RPythonAnnotator() + s = a.build_types(oof, []) + #a.translator.view() + + assert s.knowntype == bool Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 19:56:37 2005 @@ -4,6 +4,14 @@ def test_simple(): assert typeOf(1) is Signed +def test_class_hash(): + M = Meth([Signed], Signed) + def m_(self, b): + return self.a + b + m = meth(M, _name="m", _callable=m_) + C = Class("test", None, {"a": Signed}, {"m": m}) + assert type(hash(C)) == int + def test_simple_class(): C = Class("test", None, {"a": Signed}) From boria at codespeak.net Tue Oct 11 20:01:13 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Tue, 11 Oct 2005 20:01:13 +0200 (CEST) Subject: [pypy-svn] r18430 - in pypy/branch/hl-backend/pypy: rpython rpython/ootype rpython/ootype/test translator Message-ID: <20051011180113.32B4D27B5A@code1.codespeak.net> Author: boria Date: Tue Oct 11 20:01:08 2005 New Revision: 18430 Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py pypy/branch/hl-backend/pypy/rpython/rmodel.py pypy/branch/hl-backend/pypy/rpython/rpbc.py pypy/branch/hl-backend/pypy/rpython/rtyper.py pypy/branch/hl-backend/pypy/translator/translator.py Log: (Samuele, Aurelien, Boris) * Start of work on integrating ootype with r{typer, model, pbc}.py Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Tue Oct 11 20:01:08 2005 @@ -197,8 +197,8 @@ def new(CLASS): return _instance(CLASS) -def static_meth(FUNCTION, **attrs): - return _static_meth(FUNCTION, **attrs) +def static_meth(FUNCTION, name, **attrs): + return _static_meth(FUNCTION, _name=name, **attrs) def meth(METHOD, **attrs): return _meth(METHOD, **attrs) Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py Tue Oct 11 20:01:08 2005 @@ -18,7 +18,7 @@ return a + b t = Translator(f) t.annotate([int, int]) - t.specialize() + t.specialize(type_system="ootype") graph = t.flowgraphs[f] check_only_ootype(graph) @@ -32,7 +32,8 @@ t = Translator(g) t.annotate([]) - t.specialize() + + t.specialize(type_system="ootype") graph = t.flowgraphs[g] check_only_ootype(graph) Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Tue Oct 11 20:01:08 2005 @@ -74,7 +74,7 @@ F = StaticMethod([Signed, Signed], Signed) def f_(a, b): return a+b - f = static_meth(F, _name="f", _callable=f_) + f = static_meth(F, "f", _callable=f_) assert typeOf(f) == F result = f(2, 3) @@ -85,7 +85,7 @@ F = StaticMethod([Signed, Signed], Signed) def f_(a, b): return a+b - f = static_meth(F, _name="f", _callable=f_) + f = static_meth(F, "f", _callable=f_) py.test.raises(TypeError, "f(2.0, 3.0)") py.test.raises(TypeError, "f()") Modified: pypy/branch/hl-backend/pypy/rpython/rmodel.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rmodel.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rmodel.py Tue Oct 11 20:01:08 2005 @@ -4,6 +4,7 @@ from pypy.rpython.lltype import Void, Bool, Float, Signed, Char, UniChar from pypy.rpython.lltype import typeOf, LowLevelType, Ptr, PyObject from pypy.rpython.lltype import FuncType, functionptr, cast_ptr_to_int +from pypy.rpython.ootype import ootype from pypy.rpython.error import TyperError, MissingRTypeOperation # initialization states for Repr instances @@ -313,13 +314,19 @@ return getattr(v, 'concretetype', PyObjPtr) def getfunctionptr(translator, graphfunc, getconcretetype=getconcretetype): + return getcallable(translator, graphfunc, getconcretetype, FuncType, functionptr) + +def getstaticmeth(translator, graphfunc, getconcretetype=getconcretetype): + return getcallable(translator, graphfunc, getconcretetype, ootype.StaticMethod, ootype.static_meth) + +def getcallable(translator, graphfunc, getconcretetype, typ, constr): """Make a functionptr from the given Python function.""" graph = translator.getflowgraph(graphfunc) llinputs = [getconcretetype(v) for v in graph.getargs()] lloutput = getconcretetype(graph.getreturnvar()) - FT = FuncType(llinputs, lloutput) + FT = typ(llinputs, lloutput) _callable = getattr(graphfunc, '_specializedversionof_', graphfunc) - return functionptr(FT, graphfunc.func_name, graph = graph, _callable = _callable) + return constr(FT, graphfunc.func_name, graph = graph, _callable = _callable) def needsgc(classdef, nogc=False): if classdef is None: Modified: pypy/branch/hl-backend/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rpbc.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rpbc.py Tue Oct 11 20:01:08 2005 @@ -344,9 +344,8 @@ def getsignature(rtyper, func): - f = rtyper.getfunctionptr(func) + f = rtyper.getcallable(func) graph = f._obj.graph - FUNCPTR = typeOf(f) rinputs = [rtyper.bindingrepr(v) for v in graph.getargs()] if graph.getreturnvar() in rtyper.annotator.bindings: rresult = rtyper.bindingrepr(graph.getreturnvar()) Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Tue Oct 11 20:01:08 2005 @@ -26,7 +26,7 @@ from pypy.translator.unsimplify import insert_empty_block from pypy.rpython.rmodel import Repr, inputconst from pypy.rpython.rmodel import TyperError, BrokenReprTyperError -from pypy.rpython.rmodel import getfunctionptr, warning +from pypy.rpython.rmodel import getfunctionptr, getstaticmeth, warning from pypy.rpython.normalizecalls import perform_normalizations from pypy.rpython.annlowlevel import annotate_lowlevel_helper from pypy.rpython.exceptiondata import ExceptionData @@ -36,8 +36,9 @@ class RPythonTyper: - def __init__(self, annotator): + def __init__(self, annotator, type_system="lltype"): self.annotator = annotator + self.type_system = type_system self.reprs = {} self._reprs_must_call_setup = [] self._seen_reprs_must_call_setup = {} @@ -496,6 +497,18 @@ def needs_hash_support(self, cls): return cls in self.annotator.bookkeeper.needs_hash_support + def getcallable(self, graphfunc): + if self.type_system == "lltype": + return self.getfunctionptr(graphfunc) + + elif self.type_system == "ootype": + return self.getstaticmeth(graphfunc) + + def getstaticmeth(self, graphfunc): + def getconcretetype(v): + return self.bindingrepr(v).lowleveltype + return getstaticmeth(self.annotator.translator, graphfunc, getconcretetype) + def getfunctionptr(self, graphfunc): def getconcretetype(v): return self.bindingrepr(v).lowleveltype Modified: pypy/branch/hl-backend/pypy/translator/translator.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/translator.py (original) +++ pypy/branch/hl-backend/pypy/translator/translator.py Tue Oct 11 20:01:08 2005 @@ -169,7 +169,9 @@ if self.rtyper is not None: raise ValueError("cannot specialize() several times") from pypy.rpython.rtyper import RPythonTyper - self.rtyper = RPythonTyper(self.annotator) + + self.rtyper = RPythonTyper(self.annotator, + type_system=flags.pop("type_system", "lltype")) self.rtyper.specialize(**flags) def backend_optimizations(self, **kwds): From bert at codespeak.net Tue Oct 11 20:02:44 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Tue, 11 Oct 2005 20:02:44 +0200 (CEST) Subject: [pypy-svn] r18431 - pypy/branch/hl-backend/pypy/annotation Message-ID: <20051011180244.989C927B5A@code1.codespeak.net> Author: bert Date: Tue Oct 11 20:02:44 2005 New Revision: 18431 Modified: pypy/branch/hl-backend/pypy/annotation/model.py Log: - create SomeRefs Modified: pypy/branch/hl-backend/pypy/annotation/model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/model.py Tue Oct 11 20:02:44 2005 @@ -448,6 +448,8 @@ ] def annotation_to_lltype(s_val, info=None): + if isinstance(s_val, SomeRef): + return s_val.ll_ptrtype if isinstance(s_val, SomePtr): return s_val.ll_ptrtype for witness, lltype in annotation_to_ll_map: @@ -465,7 +467,10 @@ def lltype_to_annotation(T): s = ll_to_annotation_map.get(T) if s is None: - return SomePtr(T) + if isinstance(T, ootype.Class): + return SomeRef(T) + else: + return SomePtr(T) else: return s From ale at codespeak.net Tue Oct 11 20:06:11 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Tue, 11 Oct 2005 20:06:11 +0200 (CEST) Subject: [pypy-svn] r18432 - pypy/dist/pypy/translator/goal Message-ID: <20051011180611.2110427B5D@code1.codespeak.net> Author: ale Date: Tue Oct 11 20:06:09 2005 New Revision: 18432 Modified: pypy/dist/pypy/translator/goal/targetnopstandalone.py pypy/dist/pypy/translator/goal/targetrichards.py Log: A little temp change Modified: pypy/dist/pypy/translator/goal/targetnopstandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetnopstandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetnopstandalone.py Tue Oct 11 20:06:09 2005 @@ -1,13 +1,15 @@ import os, sys +from pypy.translator.test.snippet import sieve_of_eratosthenes as soe def debug(msg): os.write(2, "debug: " + msg + '\n') + # __________ Entry point __________ def entry_point(argv): - debug("done!") - return 0 + count = soe() + return count # _____ Define and setup target ___ Modified: pypy/dist/pypy/translator/goal/targetrichards.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrichards.py (original) +++ pypy/dist/pypy/translator/goal/targetrichards.py Tue Oct 11 20:06:09 2005 @@ -1,7 +1,9 @@ from pypy.translator.goal import richards +from pypy.translator.tool.taskengine import SimpleTaskEngine entry_point = richards.entry_point + # _____ Define and setup target ___ def target(*args): @@ -18,3 +20,34 @@ richards.main(iterations=5) +class Tasks(SimpleTaskEngine): + + def task_annotate(self): + pass + task_annotate.task_deps = [] + + def task + + +""" sketch of tasks for translation: + +annotate: # includes annotation and annotatation simplifications + +rtype: annotate + +backendoptimisations: rtype # make little sense otherwise + +source_llvm: backendoptimisations, rtype, annotate + +source_c: ?backendoptimisations, ?rtype, ?annotate + +compile_c : source_c + +compile_llvm: source_llvm + +run_c: compile_c + +run_llvm: compile_llvm + +""" + From arigo at codespeak.net Tue Oct 11 20:15:26 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 11 Oct 2005 20:15:26 +0200 (CEST) Subject: [pypy-svn] r18433 - pypy/dist/pypy/translator/c Message-ID: <20051011181526.0CCE727B5A@code1.codespeak.net> Author: arigo Date: Tue Oct 11 20:15:23 2005 New Revision: 18433 Modified: pypy/dist/pypy/translator/c/stackless.py Log: Improve the selection of variables to put in a heap frame across a save/resume. Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 11 20:15:23 2005 @@ -181,13 +181,7 @@ stacklessdata = self.db.stacklessdata block = self.currentblock curpos = block.operations.index(op) - - # XXX obscure: find all variables that are produced before 'op' - vars = [] - for v in block.inputargs: - vars.append(v) - for op1 in block.operations[:curpos]: - vars.append(op1.result) + vars = list(variables_to_save_across_op(block, curpos)) # get the simplified frame struct that can store these vars counts = {"long": [], @@ -284,3 +278,31 @@ "long" : "slp_retval_long", "void*" : "slp_retval_voidptr", } + + +def variables_to_save_across_op(block, opindex): + # variable lifetime detection: + # 1) find all variables that are produced before the operation + produced = {} + for v in block.inputargs: + produced[v] = True + for op1 in block.operations[:opindex]: + produced[op1.result] = True + # 2) find all variables that are used by or after the operation + consumed = {} + for op1 in block.operations[opindex:]: + for v in op1.args: + if isinstance(v, Variable): + consumed[v] = True + if isinstance(block.exitswitch, Variable): + consumed[block.exitswitch] = True + for link in block.exits: + for v in link.args: + if isinstance(v, Variable): + consumed[v] = True + # 3) variables that are atomic and not consumed after the operation + # don't have to have their lifetime extended; that leaves only + # the ones that are not atomic or consumed. + for v in produced: + if v in consumed or not v.concretetype._is_atomic(): + yield v From afa at codespeak.net Wed Oct 12 09:57:58 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 09:57:58 +0200 (CEST) Subject: [pypy-svn] r18440 - pypy/dist/pypy/translator/c Message-ID: <20051012075758.9317927B50@code1.codespeak.net> Author: afa Date: Wed Oct 12 09:57:56 2005 New Revision: 18440 Modified: pypy/dist/pypy/translator/c/stackless.py Log: stackless: try to give better function names; some comments and cleanups Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Wed Oct 12 09:57:56 2005 @@ -40,6 +40,9 @@ self.decode_table.append(('NULL', n)) def get_frame_type(self, n_integers, n_floats, n_pointers): + """Return the frame struct name, + named after the number of saved variables of each kind + """ key = n_integers, n_floats, n_pointers try: return self.frame_types[key] @@ -59,24 +62,25 @@ for line in sg.preimpl: print >> fc, line print >> fc, '#include "src/g_include.h"' + items = self.frame_types.items() items.sort() for (n_integers, n_floats, n_pointers), structname in items: - types = (['long']*n_integers + - ['double']*n_floats + - ['void *']*n_pointers) - varnames = (['l%d' % i for i in range(n_integers)] + - ['d%d' % i for i in range(n_floats)] + - ['v%d' % i for i in range(n_pointers)]) + varnames = ([('long', 'l%d' % i) for i in range(n_integers)] + + [('double', 'd%d' % i) for i in range(n_floats)] + + [('void *', 'v%d' % i) for i in range(n_pointers)]) + + # generate the struct definition fields = [] - for type, varname in zip(types, varnames): + for type, varname in varnames: fields.append('%s %s;' % (type, varname)) print >> fi, 'struct %s { slp_frame_t header; %s };' % ( structname, ' '.join(fields)) + # generate the 'save_' function arguments = ['int state'] saving_lines = [] - for type, varname in zip(types, varnames): + for type, varname in varnames: arguments.append('%s %s' % (type, varname)) saving_lines.append('((struct %s*) f)->%s = %s;' % ( structname, varname, varname)) @@ -112,7 +116,7 @@ functiontype = sg.database.gettype(lltype.Ptr(FUNC)) callexpr = '((%s) fn) (%s);' % (cdecl(functiontype, ''), ', '.join(dummyargs)) - globalretvalvartype = simplified_type(FUNC.RESULT) + globalretvalvartype = storage_type(FUNC.RESULT) if globalretvalvartype is not None: globalretvalvarname = RETVALVARS[globalretvalvartype] callexpr = '%s = (%s) %s' % (globalretvalvarname, @@ -165,11 +169,11 @@ # record extra data needed to generate the slp_*.h tables: # find the signatures of all functions slpdata = self.db.stacklessdata - argtypes = [erase_ptr_type(v.concretetype) + argtypes = [signature_type(v.concretetype) for v in self.graph.getargs()] argtypes = [T for T in argtypes if T is not lltype.Void] import sys - rettype = erase_ptr_type(self.graph.getreturnvar().concretetype) + rettype = signature_type(self.graph.getreturnvar().concretetype) FUNC = lltype.FuncType(argtypes, rettype) slpdata.registerunwindable(self.functionname, FUNC, resume_points = len(self.resumeblocks)) @@ -189,7 +193,7 @@ "void*": []} variables_to_restore = [] for v in vars: - st = simplified_type(erase_ptr_type(v.concretetype)) + st = storage_type(v.concretetype) if st is not None: # ignore the Voids varname = self.expr(v) # XXX hackish: the name of the field in the structure is @@ -233,7 +237,7 @@ varname, cdecl(vartype, ''), structname, fieldname)) retvarname = self.expr(op.result) retvartype = self.lltypename(op.result) - retvarst = simplified_type(erase_ptr_type(op.result.concretetype)) + retvarst = storage_type(op.result.concretetype) if retvarst is not None: globalretvalvarname = RETVALVARS[retvarst] lines.append('%s = (%s) %s;' % ( @@ -251,9 +255,10 @@ exception_check) -def erase_ptr_type(T): +def signature_type(T): """Return T unless it's a pointer type, in which case we return a general basic pointer type. + The returned type must have the same behaviour when put on the C stack. """ if isinstance(T, lltype.Ptr): return Address @@ -261,12 +266,14 @@ return T -def simplified_type(T): +def storage_type(T): + """Return the type, used to save values of this type + """ if T is lltype.Void: return None elif T is lltype.Float: return "double" - elif T is Address: + elif T is Address or isinstance(T, lltype.Ptr): return "void*" elif isinstance(T, lltype.Primitive): return "long" # large enough for all other primitives From ac at codespeak.net Wed Oct 12 10:18:14 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 12 Oct 2005 10:18:14 +0200 (CEST) Subject: [pypy-svn] r18441 - in pypy/branch/hl-backend/pypy/annotation: . test Message-ID: <20051012081814.2328727B50@code1.codespeak.net> Author: ac Date: Wed Oct 12 10:18:13 2005 New Revision: 18441 Modified: pypy/branch/hl-backend/pypy/annotation/model.py pypy/branch/hl-backend/pypy/annotation/test/test_model.py pypy/branch/hl-backend/pypy/annotation/unaryop.py Log: Make SomeRef not inherit SomePtr. Modified: pypy/branch/hl-backend/pypy/annotation/model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/model.py Wed Oct 12 10:18:13 2005 @@ -431,10 +431,13 @@ def can_be_none(self): return False -class SomeRef(SomePtr): - pass +class SomeRef(SomeObject): + def __init__(self, ootype): + self.ootype = ootype + from pypy.rpython import lltype +from pypy.rpython.ootype import ootype annotation_to_ll_map = [ (SomePBC({None: True}), lltype.Void), # also matches SomeImpossibleValue() @@ -449,7 +452,7 @@ def annotation_to_lltype(s_val, info=None): if isinstance(s_val, SomeRef): - return s_val.ll_ptrtype + return s_val.ootype if isinstance(s_val, SomePtr): return s_val.ll_ptrtype for witness, lltype in annotation_to_ll_map: Modified: pypy/branch/hl-backend/pypy/annotation/test/test_model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/test/test_model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/test/test_model.py Wed Oct 12 10:18:13 2005 @@ -118,6 +118,9 @@ assert isinstance(s_p, SomePtr) and s_p.ll_ptrtype == lltype.Ptr(S) s_p = ll_to_annotation(lltype.malloc(A, 0)) assert isinstance(s_p, SomePtr) and s_p.ll_ptrtype == lltype.Ptr(A) + C = ootype.Class('C', None, {}) + s_p = ll_to_annotation(ootype.new(C)) + assert isinstance(s_p, SomeRef) and s_p.ootype == C def test_annotation_to_lltype(): from pypy.rpython.rarithmetic import r_uint @@ -140,6 +143,9 @@ s_p = SomePtr(ll_ptrtype=PS) assert annotation_to_lltype(s_p) == PS py.test.raises(ValueError, "annotation_to_lltype(si0)") + C = ootype.Class('C', None, {}) + ref = SomeRef(C) + assert annotation_to_lltype(ref) == C def test_ll_union(): PS1 = lltype.Ptr(lltype.GcStruct('s')) @@ -166,6 +172,13 @@ py.test.raises(AssertionError, "unionof(SomeInteger(), SomePtr(PS1))") py.test.raises(AssertionError, "unionof(SomeObject(), SomePtr(PS1))") +def test_oo_union(): + C1 = ootype.Class("C1", None, {}) + C2 = ootype.Class("C2", C1, {}) + D = ootype.Class("D", None, {}) + assert unionof(SomeRef(C1), SomeRef(C1)) == SomeRef(C1) + + if __name__ == '__main__': for name, value in globals().items(): if name.startswith('test_'): Modified: pypy/branch/hl-backend/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/unaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/unaryop.py Wed Oct 12 10:18:13 2005 @@ -566,7 +566,7 @@ # annotation of low-level types -from pypy.annotation.model import SomePtr, ll_to_annotation, annotation_to_lltype +from pypy.annotation.model import SomePtr, SomeRef, ll_to_annotation, annotation_to_lltype class __extend__(SomePtr): def getattr(p, s_attr): @@ -592,6 +592,12 @@ def is_true(p): return SomeBool() +class __extend__(SomeRef): + def getattr(p, s_attr): + assert s_attr.is_constant(), "getattr on ref %r with non-constant field-name" % p.ootype + v = getattr(p.ootype._example(), s_attr.const) + return ll_to_annotation(v) + #_________________________________________ # memory addresses From mwh at codespeak.net Wed Oct 12 10:32:31 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 10:32:31 +0200 (CEST) Subject: [pypy-svn] r18442 - pypy/dist/pypy/translator/asm Message-ID: <20051012083231.03A7A27B50@code1.codespeak.net> Author: mwh Date: Wed Oct 12 10:32:29 2005 New Revision: 18442 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/infregmachine.py Log: change Instruction a bit; integer arguments are still integers but immediate arguments are stored as Constant(immed) which allows a more consistent way of determining which registers are used by a register, etc. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 10:32:29 2005 @@ -49,7 +49,7 @@ g = FuncGenerator(graph) g.gencode() # g.assembler.dump() - finreg = g.assembler.allocate_registers(30) +# finreg = g.assembler.allocate_registers(5) return make_func(finreg.assemble(), 'i', 'i'*len(graph.startblock.inputargs)) @@ -71,7 +71,7 @@ self.assembler = infregmachine.Assembler() for i, var in enumerate(graph.startblock.inputargs): - self.emit('LIA', self.reg(var), i) + self.emit('LIA', self.reg(var), Constant(i)) def assign_register(self, var): assert var not in self._var2reg @@ -85,7 +85,7 @@ if isinstance(var, Constant): r = self.next_register assert isinstance(var.value, int) - self.assembler.emit("LOAD", r, var.value) + self.assembler.emit("LOAD", r, var) self.next_register += 1 return r elif isinstance(var, Variable): Modified: pypy/dist/pypy/translator/asm/infregmachine.py ============================================================================== --- pypy/dist/pypy/translator/asm/infregmachine.py (original) +++ pypy/dist/pypy/translator/asm/infregmachine.py Wed Oct 12 10:32:29 2005 @@ -1,3 +1,4 @@ +from pypy.translator.asm import regalloc class Instruction(object): @@ -6,12 +7,15 @@ self.arguments = arguments def registers_used(self): - if self.name == 'LIA' or self.name == 'LOAD': - return [self.arguments[0]] - elif self.name in ('JT', 'JF', 'J'): - return [] - else: - return list(self.arguments) + return [a for a in self.arguments if isinstance(a, int)] + + def renumber(self, regmap): + def _(a): + if isinstance(a, int) and a in regmap: + return regmap[a] + else: + return a + return Instruction(self.name, map(_, self.arguments)) def __repr__(self): if self.name == 'LIA': @@ -20,10 +24,15 @@ elif self.name in ('JT', 'JF', 'J'): args = self.arguments[0] elif self.name == 'LOAD': - args = 'r%s, %s'%tuple(self.arguments) + args = 'r%s, #%s'%tuple(self.arguments) else: - args = ', '.join(['r%s'%a for a in self.arguments]) - return ' %-10s %s'%(self.name, args) + def c(x): + if isinstance(x, int): + return 'r%s'%x + else: + return str(x) + args = ', '.join(map(c, self.arguments)) + return '%-30s'%(' %-10s %s'%(self.name, args),) class Assembler(object): def __init__(self): @@ -43,10 +52,11 @@ def allocate_registers(self, nregisters): r = FiniteRegisterAssembler(nregisters) - for i in self.instructions: - if not isinstance(i, str): # labels - assert max(i.registers_used() + [0]) < nregisters - r.instructions.append(i) + r.instructions = regalloc.regalloc(self.instructions, nregisters) +# for i in r.instructions: +# if not isinstance(i, str): # labels +# assert max(i.registers_used() + [0]) < nregisters + r.dump() return r class FiniteRegisterAssembler(Assembler): @@ -68,9 +78,10 @@ return A def LIA(self, A, dest, argindex): - assert dest + 2 == argindex + 3 + assert dest + 2 == argindex.value + 3 def LOAD(self, A, dest, value): + value = value.value assert isinstance(value, int) assert -30000 < value < 30000 A.li(dest + 2, value) @@ -104,3 +115,8 @@ def MOV(self, A, dest, src): A.mr(dest + 2, src + 2) + + def EXCH(self, A, a, b): + A.xor(a, a, b) + A.xor(b, b, a) + A.xor(a, a, b) From ericvrp at codespeak.net Wed Oct 12 10:55:24 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 12 Oct 2005 10:55:24 +0200 (CEST) Subject: [pypy-svn] r18444 - pypy/dist/pypy/translator/js Message-ID: <20051012085524.1B3B327B50@code1.codespeak.net> Author: ericvrp Date: Wed Oct 12 10:55:23 2005 New Revision: 18444 Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/opaquenode.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py Log: Cleaning up. In the process to move phi node handling to the source block. This will produce cleaner (js) code where I don;t have to keep track of the previous block anymore. Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Wed Oct 12 10:55:23 2005 @@ -11,13 +11,18 @@ def __init__(self, f, js): self.f = f self.js = js + self._skip_closeblock = False def append(self, line, indentation_level=4): if indentation_level: s = self.tabstring * indentation_level else: s = '' - self.f.write(s + line + '\n') + if not line or line[-1] in '{:};' or line.lstrip()[:2] == '//': + eol = '\n' + else: + eol = ';\n' + self.f.write(s + line + eol) def comment(self, line, indentation_level=4): self.append("// " + line, indentation_level) @@ -30,10 +35,15 @@ def label(self, name): self.append("case %d:" % name, 3) - openblock = label + + def openblock(self, name): + self.append("case %d:" % name, 3) + self._currentblock = name def closeblock(self): - self.append('continue') + if not self._skip_closeblock: + self.append('break') + self._skip_closeblock = False def globalinstance(self, name, typeanddata): #self.append('%s = %s' % (name, typeanddata[1:].split('{')[1][:-1]), 0) @@ -61,15 +71,29 @@ #self.llvm("implementation", 0) pass - def br_uncond(self, blockname): - self.append('prevblock = block') - self.append('block = %d' % blockname) - #self.llvm("br label %s" %(blockname,)) - - def br(self, cond, blockname_false, blockname_true): - self.append('prevblock = block') - self.append('block = %s ? %d : %d' % (cond, blockname_true, blockname_false)) - #self.llvm("br bool %s, label %s, label %s" % (cond, blockname_true, blockname_false)) + def br_uncond(self, block): + self.append('prevblock = ' + str(self._currentblock)) + if block == self._currentblock + 1: + self._skip_closeblock = True + else: + self.append('block = ' + str(block)) + + def br(self, cond, block_false, block_true): + self.append('prevblock = ' + str(self._currentblock)) + self.append('if (%s) {' % cond) + if block_true == self._currentblock + 1: + self._skip_closeblock = True + else: + self.append('block = ' + str(block_true), 5) + self.append('break', 5) + if block_false == self._currentblock + 1: + self._skip_closeblock = True + else: + self.append('} else {') + self.append('block = ' + str(block_false), 5) + self.append('break', 5) + self.append('}') + self.comment('block = %s ? %d : %d' % (cond, block_true, block_false)) def switch(self, intty, cond, defaultdest, value_label): labels = '' @@ -91,28 +115,29 @@ self.append("function %s {" % self.decl, 0) if usedvars: self.append("var %s" % ', '.join(usedvars.keys()), 1) - self.append("var block = 0", 1) - self.append("while (block != undefined) {", 1) + self.append("for (var block = 0;;) {", 1) self.append("switch (block) {", 2) def closefunc(self): - self.append("} // end of switch (block)", 2) - self.append("} // end of while (block != undefined)", 1) - self.append("} // end of function %s" % self.decl, 0) + self.append("}", 2) + self.append("}", 1) + self.append("};", 0) def ret(self, type_, ref): if type_ == 'void': self.append("return") else: self.append("return " + ref) + self._skip_closeblock = True + + def phi(self, targetvar, type_, refs, blocks): + assert refs and len(refs) == len(blocks), "phi node requires blocks" + mergelist = ", ".join( + ["[%s, %s]" % item + for item in zip(refs, blocks)]) + s = "%s = phi %s %s" % (targetvar, type_, mergelist) + self.llvm(s) - def phi(self, targetvar, type_, refs, blocknames): - assert refs and len(refs) == len(blocknames), "phi node requires blocks" - #mergelist = ", ".join( - # ["[%s, %s]" % item - # for item in zip(refs, blocknames)]) - #s = "%s = phi %s %s" % (targetvar, type_, mergelist) - #self.llvm(s) all_refs_identical = True for ref in refs: if ref != refs[0]: @@ -122,17 +147,17 @@ if targetvar != refs[0]: self.append('%s = %s' % (targetvar, refs[0])) else: - if len(blocknames) == 1: + if len(blocks) == 1: self.append('%s = %s' % (targetvar, refs[i])) else: n = 0 - for i, blockname in enumerate(blocknames): + for i, block in enumerate(blocks): if targetvar != refs[i]: if n > 0: s = 'else ' else: s = '' - self.append('%sif (prevblock == %d) %s = %s' % (s, blockname, targetvar, refs[i])) + self.append('%sif (prevblock == %d) %s = %s' % (s, block, targetvar, refs[i])) n += 1 def binaryop(self, name, targetvar, type_, ref1, ref2): @@ -155,10 +180,10 @@ self.append('%s = %s(%s)' % (targetvar, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): - self.comment('codewriter cast 1 targettype=%(targettype)s, targetvar=%(targetvar)s, fromtype=%(fromtype)s, fromvar=%(fromvar)s' % locals()) + #self.comment('codewriter cast 1 targettype=%(targettype)s, targetvar=%(targetvar)s, fromtype=%(fromtype)s, fromvar=%(fromvar)s' % locals()) if fromtype == 'void' and targettype == 'void': return - self.comment('codewriter cast 2') + #self.comment('codewriter cast 2') if targettype == fromtype: self.append("%(targetvar)s = %(fromvar)s" % locals()) elif targettype in ('int','uint',): Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Wed Oct 12 10:55:23 2005 @@ -22,7 +22,7 @@ self.db = db assert isinstance(type_, lltype.FuncType) self.type_ = type_ - self.ref = self.make_ref('%functiontype', '') + self.ref = self.make_ref('functiontype', '') def __str__(self): return "" % self.ref Modified: pypy/dist/pypy/translator/js/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/js/opaquenode.py (original) +++ pypy/dist/pypy/translator/js/opaquenode.py Wed Oct 12 10:55:23 2005 @@ -7,7 +7,7 @@ assert isinstance(opaquetype, lltype.OpaqueType) self.db = db self.opaquetype = opaquetype - self.ref = "%%opaquetype.%s" % (opaquetype.tag) + self.ref = "opaquetype." + opaquetype.tag def __str__(self): return "" %(self.ref,) Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Wed Oct 12 10:55:23 2005 @@ -212,7 +212,7 @@ 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]) - self.codewriter.comment(op.opname) + self.codewriter.comment('next line='+op.opname) self.codewriter.cast(targetvar, fromtype, fromvar, targettype) same_as = cast_primitive @@ -412,9 +412,11 @@ 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) + #self.codewriter.getelementptr(tmpvar, structtype, struct, + # ("uint", index)) + #self.codewriter.load(targetvar, targettype, tmpvar) + self.codewriter.comment('XXX getfield') + self.codewriter.load(targetvar, struct, (index,)) else: self._skipped(op) @@ -433,9 +435,11 @@ 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, - ("uint", index)) - self.codewriter.store(valuetype, valuevar, tmpvar) + #self.codewriter.getelementptr(tmpvar, structtype, struct, + # ("uint", index)) + #self.codewriter.store(valuetype, valuevar, tmpvar) + self.codewriter.comment('XXX setfield') + self.codewriter.store(struct, (index,), valuevar) else: self._skipped(op) Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Wed Oct 12 10:55:23 2005 @@ -83,7 +83,7 @@ self.db = db self.value = value self.structtype = self.value._TYPE - prefix = '%structinstance.' + prefix = 'structinstance.' name = str(value).split()[1] self.ref = self.make_ref(prefix, name) self._get_ref_cache = None @@ -124,8 +124,6 @@ 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(), From cfbolz at codespeak.net Wed Oct 12 11:34:09 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 12 Oct 2005 11:34:09 +0200 (CEST) Subject: [pypy-svn] r18445 - in pypy/extradoc/sprintinfo: . paris Message-ID: <20051012093409.888D627B51@code1.codespeak.net> Author: cfbolz Date: Wed Oct 12 11:34:07 2005 New Revision: 18445 Added: pypy/extradoc/sprintinfo/paris/paris-2005-stackless-discussion.txt - copied unchanged from r18382, pypy/extradoc/sprintinfo/paris-2005-stackless-discussion.txt Removed: pypy/extradoc/sprintinfo/paris-2005-stackless-discussion.txt Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt Log: add planning for today. move stackless file to paris dir Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-planning.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-planning.txt Wed Oct 12 11:34:07 2005 @@ -10,33 +10,40 @@ ca. 01:00 pm lunch time thursday: breakday (for some of us: eu-consortium meeting) +(during the breakday the big room will be needed for the meeting +from 1pm, so if somebody wants to work in the afternoon, he has to +go to one of the small rooms) - -pairing tuesday +pairing wednesday ======================= stackless/cps: (same group continues, "re-"pairing inside) christian, armin Valentino, Amaury Adrien, Anders - +(see stackless status text soon to be checked in) + andrew/michael: powerpc-backend (getting there, continues) bert, samuele, boris, arre, aurelien: different specialization to more HL-backends (defined the "ootypes" model, like the "lltypes" but more OO-ish; will start to work on the ootyper, as a branch of the rtyper for now; same group continues - and may split in two subgroups soon -- backend and ootyper.) + and has split in two subgroups soon -- annotator and ootyper.) -llinterpreter: Carl, Holger +llinterpreter: Carl, (Armin later) (starting on the data model of the ll flow graphs, continues) -next status meeting: wed 10:30 +next status meeting: fri 10:30 later wednesday: discussing compiler & phase 2 work/tasks for the sprint WP09/WP10 +on friday: + * short presentation from logilab/dfki about logic programming/AOP + * (maybe) presentation about GC work during Summer of Code + peoples present --------------------- From cfbolz at codespeak.net Wed Oct 12 11:36:23 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 12 Oct 2005 11:36:23 +0200 (CEST) Subject: [pypy-svn] r18446 - pypy/dist/pypy/doc/image Message-ID: <20051012093623.0E7EA27B50@code1.codespeak.net> Author: cfbolz Date: Wed Oct 12 11:36:21 2005 New Revision: 18446 Modified: pypy/dist/pypy/doc/image/lattice1.dot Log: change lattice1 to match the version in the draft file Modified: pypy/dist/pypy/doc/image/lattice1.dot ============================================================================== --- pypy/dist/pypy/doc/image/lattice1.dot (original) +++ pypy/dist/pypy/doc/image/lattice1.dot Wed Oct 12 11:36:21 2005 @@ -4,11 +4,11 @@ Top -> "*instances*" -> Bottom; "*instances*" -> None; NullableStr -> None; - Top -> "*callables*" -> Bottom; - "*callables*" -> None; + Top -> "*PBCs*" -> Bottom; + "*PBCs*" -> None; Top -> "*lists*" -> None -> Bottom; "*lists*" [shape=box]; "*instances*" [shape=box]; - "*callables*" [shape=box]; + "*PBCs*" [shape=box]; } From cfbolz at codespeak.net Wed Oct 12 11:36:45 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 12 Oct 2005 11:36:45 +0200 (CEST) Subject: [pypy-svn] r18447 - pypy/dist/pypy/doc/image Message-ID: <20051012093645.7D7F927B50@code1.codespeak.net> Author: cfbolz Date: Wed Oct 12 11:36:43 2005 New Revision: 18447 Added: pypy/dist/pypy/doc/image/JIT.dot Log: small example graph about how the JIT /might/ work Added: pypy/dist/pypy/doc/image/JIT.dot ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/image/JIT.dot Wed Oct 12 11:36:43 2005 @@ -0,0 +1,56 @@ +digraph JIT { + + subgraph top { + rank=same; + block0 [label = "..."] + block0s [label = "..."] + block0s1 [label = "..."] + } + subgraph bottom { + rank=same; + block2 [label = "inputargs: v4\n...", shape=box] + block3 [label = "inputargs: v5\n...", shape=box] + block2s [label = "inputargs: v4\n...", shape=box] + block3s [label = "inputargs: v5\n...", shape=box] + block2s1 [label = "inputargs: v4\n...", shape=box] + block3s1 [label = "inputargs: v5\n...", shape=box] + } + block1 [label = "inputargs: struct_1\n\nv1 = getfield(struct_1, ('co'))\nv2 = int_add(v1, (1)) \nv3 = cast_int_to_bool(v2) \n\nexitswitch: v2", shape=octagon] + block0 -> block1 + block1 -> block2 [label="True: v2"] + block1 -> block3 [label="False: v2"] + + block0_5s [label = "inputargs: struct_1\n\nv1 = ptr_eq(struct_1, (const_struct_a))\n\nexitswitch: v1", shape=octagon] + block1s [label = "inputargs: struct_1\n\nv1 = getfield(struct_1, ('co'))\nv2 = int_add(v1, (1)) \nv3 = cast_int_to_bool(v2) \n\nexitswitch: v2", shape=octagon] + block1a [label = "inputargs: struct_1\n\nv1 = getfield((const_struct_a), ('co'))\nv2 = int_add(v1, (1)) \nv3 = cast_int_to_bool(v2) \n\nexitswitch: v2", shape=octagon] + block0s -> block0_5s + block0_5s -> block1s [label="False: struct_1"] + block0_5s -> block1a [label="True: "] + block1s -> block2s [label="True: v2"] + block1s -> block3s [label="False: v2"] + block1a -> block2s [label="True: v2"] + block1a -> block3s [label="False: v2"] + + block0_5s1 [label = "inputargs: struct_1\n\nv1 = ptr_eq(struct_1, (const_struct_a))\n\nexitswitch: v1", shape=octagon] + block1s1 [label = "inputargs: struct_1\n\nv1 = getfield(struct_1, ('co'))\nv2 = int_add(v1, (1)) \nv3 = cast_int_to_bool(v2) \n\nexitswitch: v2", shape=octagon] + block1a1 [label = "inputargs: \n\nv2 = int_add((2), (1)) \nv3 = cast_int_to_bool(v2) \n\nexitswitch: v2", shape=octagon] + block0s1 -> block0_5s1 + block0_5s1 -> block1s1 [label="False: struct_1"] + block0_5s1 -> block1a1 [label="True: "] + block1s1 -> block2s1 [label="True: v2"] + block1s1 -> block3s1 [label="False: v2"] + block1a1 -> block2s1 [label="True: v2"] + block1a1 -> block3s1 [label="False: v2"] + + block0s2 [label = "..."] + block0_5s2 [label = "inputargs: struct_1\n\nv1 = ptr_eq(struct_1, (const_struct_a))\n\nexitswitch: v1", shape=octagon] + block1s2 [label = "inputargs: struct_1\n\nv1 = getfield(struct_1, ('co'))\nv2 = int_add(v1, (1)) \nv3 = cast_int_to_bool(v2) \n\nexitswitch: v2", shape=octagon] + block2s2 [label = "inputargs: v4\n...", shape=box] + block3s2 [label = "inputargs: v5\n...", shape=box] + block0s2 -> block0_5s2 + block0_5s2 -> block1s2 [label="False: struct_1"] + block0_5s2 -> block2s2 [label="True: (3)"] + block1s2 -> block2s2 [label="True: v3"] + block1s2 -> block3s2 [label="False: v3"] + +} From afa at codespeak.net Wed Oct 12 11:39:26 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 11:39:26 +0200 (CEST) Subject: [pypy-svn] r18448 - pypy/dist/pypy/translator/c Message-ID: <20051012093926.D0BCD27B51@code1.codespeak.net> Author: afa Date: Wed Oct 12 11:39:25 2005 New Revision: 18448 Modified: pypy/dist/pypy/translator/c/stackless.py Log: stackless refactoring: remove fixed lists of types Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Wed Oct 12 11:39:25 2005 @@ -11,7 +11,6 @@ from pypy.translator.c.support import cdecl from pypy.translator.c.funcgen import FunctionCodeGenerator - class StacklessData: def __init__(self): @@ -39,15 +38,17 @@ for n in range(1, resume_points): self.decode_table.append(('NULL', n)) - def get_frame_type(self, n_integers, n_floats, n_pointers): + def get_frame_type(self, counts): """Return the frame struct name, - named after the number of saved variables of each kind + named after the number of saved variables of each kind. + counts is a sequence of numbers, ordered like STATE_TYPES """ - key = n_integers, n_floats, n_pointers + key = tuple(counts) try: return self.frame_types[key] except KeyError: - name = 'slp_frame_%d_%d_%d_s' % key + nums = "_".join([str(c) for c in key]) + name = 'slp_frame_%s_s' % nums self.frame_types[key] = name return name @@ -65,10 +66,11 @@ items = self.frame_types.items() items.sort() - for (n_integers, n_floats, n_pointers), structname in items: - varnames = ([('long', 'l%d' % i) for i in range(n_integers)] + - [('double', 'd%d' % i) for i in range(n_floats)] + - [('void *', 'v%d' % i) for i in range(n_pointers)]) + for counts, structname in items: + varnames = [] + for count, vartype in zip(counts, STATE_TYPES): + varnames.extend([(vartype.ctype, '%s%d' % (vartype.prefix, i)) + for i in range(count)]) # generate the struct definition fields = [] @@ -118,9 +120,8 @@ ', '.join(dummyargs)) globalretvalvartype = storage_type(FUNC.RESULT) if globalretvalvartype is not None: - globalretvalvarname = RETVALVARS[globalretvalvartype] - callexpr = '%s = (%s) %s' % (globalretvalvarname, - globalretvalvartype, + callexpr = '%s = (%s) %s' % (globalretvalvartype.global_name, + globalretvalvartype.ctype, callexpr) print >> fi, '\t' + callexpr print >> fi, '\tbreak;' @@ -172,7 +173,6 @@ argtypes = [signature_type(v.concretetype) for v in self.graph.getargs()] argtypes = [T for T in argtypes if T is not lltype.Void] - import sys rettype = signature_type(self.graph.getreturnvar().concretetype) FUNC = lltype.FuncType(argtypes, rettype) slpdata.registerunwindable(self.functionname, FUNC, @@ -188,33 +188,29 @@ vars = list(variables_to_save_across_op(block, curpos)) # get the simplified frame struct that can store these vars - counts = {"long": [], - "double": [], - "void*": []} + counts = dict([(type, []) for type in STATE_TYPES]) variables_to_restore = [] for v in vars: st = storage_type(v.concretetype) if st is not None: # ignore the Voids varname = self.expr(v) - # XXX hackish: the name of the field in the structure is - # computed from the 1st letter of the 'st' type, counting - # from 0 for each of the 'st' types independently + # The name of the field in the structure is computed from + # the prefix of the 'st' type, counting from 0 for each + # of the 'st' types independently variables_to_restore.append((v, '%s%d' % ( - st[0], len(counts[st])))) - counts[st].append('(%s)%s' % (st, varname)) - structname = stacklessdata.get_frame_type(len(counts["long"]), - len(counts["double"]), - len(counts["void*"])) + st.prefix, len(counts[st])))) + counts[st].append('(%s)%s' % (st.ctype, varname)) + structname = stacklessdata.get_frame_type([len(counts[st]) for st in STATE_TYPES]) # reorder the vars according to their type - vars = counts["long"] + counts["double"] + counts["void*"] + vars = sum([counts[st] for st in STATE_TYPES],[]) # generate the 'save:' line, e.g. # save_0: return (int) save_frame_1(0, (long) n); savelabel = 'save_%d' % len(self.savelines) - # Find the globally unique number for our state. - # It is the total number of saved states so far + # The globally unique number for our state + # is the total number of saved states so far globalstatecounter = len(stacklessdata.decode_table) + len(self.savelines) arguments = ['%d' % globalstatecounter] + vars @@ -239,7 +235,7 @@ retvartype = self.lltypename(op.result) retvarst = storage_type(op.result.concretetype) if retvarst is not None: - globalretvalvarname = RETVALVARS[retvarst] + globalretvalvarname = retvarst.global_name lines.append('%s = (%s) %s;' % ( retvarname, cdecl(retvartype, ''), globalretvalvarname)) lines.append('goto %s;' % (resumelabel,)) @@ -266,27 +262,32 @@ return T +class StateVariableType: + def __init__(self, ctype, prefix, global_name): + self.ctype = ctype + self.prefix = prefix + self.global_name = global_name + +STATE_TYPES = [ + StateVariableType('long', 'l', 'slp_retval_long'), + StateVariableType('void*', 'p', 'slp_retval_voidptr'), + StateVariableType('double', 'd', 'slp_retval_double'), + ] + def storage_type(T): - """Return the type, used to save values of this type + """Return the type used to save values of this type """ if T is lltype.Void: return None elif T is lltype.Float: - return "double" + return STATE_TYPES[ 2 ] elif T is Address or isinstance(T, lltype.Ptr): - return "void*" + return STATE_TYPES[ 1 ] elif isinstance(T, lltype.Primitive): - return "long" # large enough for all other primitives + return STATE_TYPES[ 0 ] # long is large enough for all other primitives else: raise Exception("don't know about %r" % (T,)) -RETVALVARS = { - "double": "slp_retval_double", - "long" : "slp_retval_long", - "void*" : "slp_retval_voidptr", - } - - def variables_to_save_across_op(block, opindex): # variable lifetime detection: # 1) find all variables that are produced before the operation From ericvrp at codespeak.net Wed Oct 12 11:49:18 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 12 Oct 2005 11:49:18 +0200 (CEST) Subject: [pypy-svn] r18449 - in pypy/dist/pypy/translator/llvm: . module Message-ID: <20051012094918.9CE4527B50@code1.codespeak.net> Author: ericvrp Date: Wed Oct 12 11:49:16 2005 New Revision: 18449 Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py pypy/dist/pypy/translator/llvm/externs2ll.py pypy/dist/pypy/translator/llvm/gc.py pypy/dist/pypy/translator/llvm/module/genexterns.c Log: some code to make this compile on OSX 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 Oct 12 11:49:16 2005 @@ -82,13 +82,19 @@ use_gcc = True profile = False + cleanup = False + + if sys.platform == 'darwin': + gc_libs_path = '-L/sw/lib -ldl' + else: + gc_libs_path = '-static' cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, OPTIMIZATION_SWITCHES, b)] if not use_gcc: cmds.append("llc %s %s.bc -f -o %s.s" % (genllvm.exceptionpolicy.llc_options(), b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) if exe_name: - cmd = "gcc %s.o %s -lm -ldl -pipe -o %s" % (b, gc_libs, exe_name) + cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) cmds.append(cmd) object_files.append("%s.o" % b) else: @@ -100,13 +106,13 @@ else: cmd += ' -fomit-frame-pointer' cmds.append(cmd) - cmd = "gcc %s.o %s -lm -ldl -pipe -o %s" % (b, gc_libs, exe_name) + cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) if profile: cmd += ' -pg' cmds.append(cmd) source_files.append("%s.c" % b) - if exe_name and not profile: + if cleanup and exe_name and not profile: cmds.append('strip ' + exe_name) upx = os.popen('which upx').read() if upx: #compress file even further Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Wed Oct 12 11:49:16 2005 @@ -1,4 +1,5 @@ import os +import sys import types import urllib @@ -11,10 +12,20 @@ def get_ll(ccode, function_names): + filename = str(udir.join("ccode.c")) + f = open(filename, "w") + f.write(ccode) + f.close() - # goto codespeak and compile our c code - request = urllib.urlencode({'ccode':ccode}) - llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() + if os.popen('which llvm-gcc').read(): #local llvm CFE available + #log('using local llvm-gcc') + plain = filename[:-2] + os.system("llvm-gcc -S %s.c -o %s.ll 2>&1" % (plain, plain)) + llcode = open(plain + '.ll').read() + else: #as fallback use remove CFE. XXX local and remote should be similar machines! + #log('falling back on remote llvm-gcc') + request = urllib.urlencode({'ccode':ccode}) # goto codespeak and compile our c code + llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() # strip lines ll_lines = [] @@ -134,13 +145,14 @@ include_files.append(j(j(os.path.dirname(extfunc.__file__), "src"), f + ".h")) for f in include_files: - ccode.append(open(f).read()) + s = open(f).read() + if f.find('genexterns.c'): + if sys.platform == 'darwin': + python_h = '"/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3/Python.h"' + else: + python_h = '' + s = s.replace('__PYTHON_H__', python_h) + ccode.append(s) ccode = "".join(ccode) - if debug: - filename = udir.join("ccode.c") - f = open(str(filename), "w") - f.write(ccode) - f.close() - return get_ll(ccode, function_names + support_functions) Modified: pypy/dist/pypy/translator/llvm/gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/gc.py (original) +++ pypy/dist/pypy/translator/llvm/gc.py Wed Oct 12 11:49:16 2005 @@ -25,7 +25,8 @@ gcpolicy = gcpolicy or 'boehm' from os.path import exists - boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') + boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') or \ + exists('/sw/lib/libgc.so') or exists('/sw/lib/libgc.a') if gcpolicy == 'boehm' and not boehm_on_path: log.gc.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc') gcpolicy = 'none' Modified: pypy/dist/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm/module/genexterns.c Wed Oct 12 11:49:16 2005 @@ -19,7 +19,9 @@ #include #include #include -#include + +//the placeholder in the next line gets replaced by the actual python.h path +#include __PYTHON_H__ // Do this manually from python :-( //#include "ll_os.h" From tismer at codespeak.net Wed Oct 12 11:57:38 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 11:57:38 +0200 (CEST) Subject: [pypy-svn] r18450 - pypy/dist/pypy/translator/goal Message-ID: <20051012095738.A4C4827B50@code1.codespeak.net> Author: tismer Date: Wed Oct 12 11:57:37 2005 New Revision: 18450 Added: pypy/dist/pypy/translator/goal/targetrpystonedalone.py (contents, props changed) Log: added rpystone as a stand-alone target. Todo: make it parameterized, maybe add richards for benchmakrs? Added: pypy/dist/pypy/translator/goal/targetrpystonedalone.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/goal/targetrpystonedalone.py Wed Oct 12 11:57:37 2005 @@ -0,0 +1,14 @@ +import os, sys +from pypy.translator.test import rpystone + +# __________ Entry point __________ + +def entry_point(argv): + count = rpystone.pystones(20000000) + return count + +# _____ Define and setup target ___ + +def target(*args): + return entry_point, None + From tismer at codespeak.net Wed Oct 12 12:00:22 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 12:00:22 +0200 (CEST) Subject: [pypy-svn] r18451 - pypy/extradoc/sprintinfo/paris Message-ID: <20051012100022.3C4A527B53@code1.codespeak.net> Author: tismer Date: Wed Oct 12 12:00:19 2005 New Revision: 18451 Added: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt - copied unchanged from r18448, pypy/extradoc/sprintinfo/paris/paris-2005-stackless-discussion.txt pypy/extradoc/sprintinfo/paris/stackless-workplan.txt (contents, props changed) Removed: pypy/extradoc/sprintinfo/paris/paris-2005-stackless-discussion.txt Log: new document on stackless work plan Added: pypy/extradoc/sprintinfo/paris/stackless-workplan.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris/stackless-workplan.txt Wed Oct 12 12:00:19 2005 @@ -0,0 +1,51 @@ +=============================== +SDG Stackless Development Group +=============================== + +People: +------- + + + +improving / refactoring +----------------------- + +- move stack check out of stackless.h, let it + either unwind or raise RuntimeError + +- always use automatic stack check detection + by default, and test: + + - test_annotated.test_recursion_detection() + - pypy-c running CPython?s test_builtins.py + +- make Stacklessness a translate_pypy option + +- add some documentation about how to make + a stand-alone target + +performance evaluation +---------------------- + +- merge stackless support and exception handling + to produce just one if clause. Use smnall test + programs to measure the effect (see below). + +- write smaller stand-alone applications + (rpystone, richards), provide benchmark + +- check the efect of false branch predicition + (if slp_frame_stack_bottom etc.) + +- instrument generated code to provide statistics + + - do some source ordering by frequency + + +large open tasks +---------------- + +- design an interface for RPython code to manipulate + the frame chains + +- expose to app-level a greenlet built-in module From afa at codespeak.net Wed Oct 12 12:02:42 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 12:02:42 +0200 (CEST) Subject: [pypy-svn] r18452 - pypy/dist/pypy/translator/goal Message-ID: <20051012100242.DF67C27B53@code1.codespeak.net> Author: afa Date: Wed Oct 12 12:02:41 2005 New Revision: 18452 Modified: pypy/dist/pypy/translator/goal/driver.py pypy/dist/pypy/translator/goal/translate_pypy.py Log: (afa, valentino) --stackless option for translate_pypy Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Wed Oct 12 12:02:41 2005 @@ -16,6 +16,7 @@ DEFAULT_OPTIONS = optparse.Values(defaults={ 'gc': 'ref', + 'stackless': False, 'debug': True, 'insist': False, 'backend': 'c', @@ -189,6 +190,7 @@ gcpolicy = gc.NoneGcPolicy cbuilder = translator.cbuilder(standalone=standalone, gcpolicy=gcpolicy) + cbuilder.stackless = opt.stackless c_source_filename = cbuilder.generate_source() self.log.info("written: %s" % (c_source_filename,)) self.cbuilder = cbuilder 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 Oct 12 12:02:41 2005 @@ -49,6 +49,7 @@ '1_backend': [OPT(('-b', '--backend'), "Backend", ['c', 'llvm'])], '2_gc': [OPT(('--gc',), "Garbage collector", ['boehm', 'ref', 'none'])], + '3_stackless': [OPT(('--stackless',), "Stackless code generation", True)], }, @@ -97,6 +98,7 @@ 'gc': 'boehm', 'backend': 'c', + 'stackless': False, 'batch': False, 'text': False, From tismer at codespeak.net Wed Oct 12 12:04:14 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 12:04:14 +0200 (CEST) Subject: [pypy-svn] r18453 - pypy/extradoc/sprintinfo Message-ID: <20051012100414.CC46627B55@code1.codespeak.net> Author: tismer Date: Wed Oct 12 12:04:12 2005 New Revision: 18453 Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt Log: added link to stackless work plan Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-planning.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-planning.txt Wed Oct 12 12:04:12 2005 @@ -21,7 +21,8 @@ christian, armin Valentino, Amaury Adrien, Anders -(see stackless status text soon to be checked in) + +(see stackless status text http://codespeak.net/pypy/extradoc/sprintinfo/paris/stackless-workplan.txt) andrew/michael: powerpc-backend (getting there, continues) From tismer at codespeak.net Wed Oct 12 12:05:28 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 12:05:28 +0200 (CEST) Subject: [pypy-svn] r18454 - pypy/dist/pypy/translator/c Message-ID: <20051012100528.9E04B27B57@code1.codespeak.net> Author: tismer Date: Wed Oct 12 12:05:27 2005 New Revision: 18454 Modified: pypy/dist/pypy/translator/c/genc.py Log: derived CBuilder from object, since I needed to use a property for debugging Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Wed Oct 12 12:05:27 2005 @@ -11,7 +11,7 @@ from pypy.rpython import lltype from pypy.tool.udir import udir -class CBuilder: +class CBuilder(object): c_source_filename = None _compiled = False symboltable = None @@ -23,7 +23,7 @@ if libraries is None: libraries = [] - self.libraries = libraries + self.libraries = libraries def generate_source(self): assert self.c_source_filename is None From boria at codespeak.net Wed Oct 12 12:09:00 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Wed, 12 Oct 2005 12:09:00 +0200 (CEST) Subject: [pypy-svn] r18455 - pypy/branch/hl-backend/pypy/rpython Message-ID: <20051012100900.55D3C27B53@code1.codespeak.net> Author: boria Date: Wed Oct 12 12:08:58 2005 New Revision: 18455 Modified: pypy/branch/hl-backend/pypy/rpython/rpbc.py pypy/branch/hl-backend/pypy/rpython/rtyper.py Log: (Samuele, Boris) * deref() helper in rtyper.py * Both tests now pass in test_ooclean.py! Modified: pypy/branch/hl-backend/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rpbc.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rpbc.py Wed Oct 12 12:08:58 2005 @@ -345,7 +345,7 @@ def getsignature(rtyper, func): f = rtyper.getcallable(func) - graph = f._obj.graph + graph = rtyper.deref(f).graph rinputs = [rtyper.bindingrepr(v) for v in graph.getargs()] if graph.getreturnvar() in rtyper.annotator.bindings: rresult = rtyper.bindingrepr(graph.getreturnvar()) @@ -391,7 +391,7 @@ def get_args_ret_s(self): f, _, _ = self.get_signature() - graph = f._obj.graph + graph = self.rtyper.deref(f).graph rtyper = self.rtyper return [rtyper.binding(arg) for arg in graph.getargs()], rtyper.binding(graph.getreturnvar()) @@ -419,7 +419,7 @@ def rtype_simple_call(self, hop): f, rinputs, rresult = self.function_signatures().itervalues().next() - if getattr(f._obj.graph, 'normalized_for_calls', False): + if getattr(self.rtyper.deref(f).graph, 'normalized_for_calls', False): # should not have an argument count mismatch assert len(rinputs) == hop.nb_args-1, "normalization bug" vlist = hop.inputargs(self, *rinputs) @@ -446,7 +446,7 @@ f, rinputs, rresult = self.function_signatures().itervalues().next() # the function arguments may have been normalized by normalizecalls() # already - if getattr(f._obj.graph, 'normalized_for_calls', False): + if getattr(self.rtyper.deref(f).graph, 'normalized_for_calls', False): vlist = hop.inputargs(self, Void, *rinputs) vlist = vlist[:1] + vlist[2:] else: Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Wed Oct 12 12:08:58 2005 @@ -22,6 +22,7 @@ from pypy.rpython.lltype import LowLevelType, Ptr, ContainerType from pypy.rpython.lltype import FuncType, functionptr, typeOf, RuntimeTypeInfo from pypy.rpython.lltype import attachRuntimeTypeInfo, Primitive +from pypy.rpython.ootype import ootype from pypy.tool.sourcetools import func_with_new_name, valid_identifier from pypy.translator.unsimplify import insert_empty_block from pypy.rpython.rmodel import Repr, inputconst @@ -38,7 +39,11 @@ def __init__(self, annotator, type_system="lltype"): self.annotator = annotator + + if type_system not in ("lltype", "ootype"): + raise TyperError("Unknown type system %r!" % type_system) self.type_system = type_system + self.reprs = {} self._reprs_must_call_setup = [] self._seen_reprs_must_call_setup = {} @@ -497,6 +502,16 @@ def needs_hash_support(self, cls): return cls in self.annotator.bookkeeper.needs_hash_support + def deref(self, obj): + """Derefernce obj if it is a pointer.""" + if self.type_system == "ootype": + assert isinstance(typeOf(obj), ootype.OOType) + return obj + elif self.type_system == "lltype": + assert isinstance(typeOf(obj), Ptr) + + return obj._obj + def getcallable(self, graphfunc): if self.type_system == "lltype": return self.getfunctionptr(graphfunc) From tismer at codespeak.net Wed Oct 12 12:14:26 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 12:14:26 +0200 (CEST) Subject: [pypy-svn] r18456 - pypy/dist/pypy/translator/c Message-ID: <20051012101426.699E027B53@code1.codespeak.net> Author: tismer Date: Wed Oct 12 12:14:25 2005 New Revision: 18456 Modified: pypy/dist/pypy/translator/c/stackless.py Log: removed direct references to concretetype, used lltypemap() instead. Although I think this should be refactored by providing some default, so concretetype is always valid. Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Wed Oct 12 12:14:25 2005 @@ -170,10 +170,10 @@ # record extra data needed to generate the slp_*.h tables: # find the signatures of all functions slpdata = self.db.stacklessdata - argtypes = [signature_type(v.concretetype) + argtypes = [signature_type(self.lltypemap(v)) for v in self.graph.getargs()] argtypes = [T for T in argtypes if T is not lltype.Void] - rettype = signature_type(self.graph.getreturnvar().concretetype) + rettype = signature_type(self.lltypemap(self.graph.getreturnvar())) FUNC = lltype.FuncType(argtypes, rettype) slpdata.registerunwindable(self.functionname, FUNC, resume_points = len(self.resumeblocks)) @@ -191,7 +191,7 @@ counts = dict([(type, []) for type in STATE_TYPES]) variables_to_restore = [] for v in vars: - st = storage_type(v.concretetype) + st = storage_type(self.lltypemap(v)) if st is not None: # ignore the Voids varname = self.expr(v) # The name of the field in the structure is computed from @@ -233,7 +233,7 @@ varname, cdecl(vartype, ''), structname, fieldname)) retvarname = self.expr(op.result) retvartype = self.lltypename(op.result) - retvarst = storage_type(op.result.concretetype) + retvarst = storage_type(self.lltypemap(op.result)) if retvarst is not None: globalretvalvarname = retvarst.global_name lines.append('%s = (%s) %s;' % ( From afa at codespeak.net Wed Oct 12 12:19:31 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 12:19:31 +0200 (CEST) Subject: [pypy-svn] r18457 - pypy/dist/pypy/translator/c/src Message-ID: <20051012101931.9530F27B42@code1.codespeak.net> Author: afa Date: Wed Oct 12 12:19:29 2005 New Revision: 18457 Added: pypy/dist/pypy/translator/c/src/stack.h Log: afa: intermediate check-in, changing machines Added: pypy/dist/pypy/translator/c/src/stack.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/stack.h Wed Oct 12 12:19:29 2005 @@ -0,0 +1,28 @@ + +/************************************************************/ + /*** C header subsection: stack operations ***/ + +static stack_base_pointer = NULL; + +char LL_stack_too_big(void) +{ + char local; + long result; + int simple_check = MAX_STACK_SIZE / 2; + + if( stack_base_pointer == NULL ) + stack_base_pointer = &local; + + /* compute the difference between local variable and + * and a stack origin pointer + */ + result = &local - slp_base_stack_pointer; + if (-simple_check < result && result < simple_check){ + return 0; + } + return 1; +} + + + + From tismer at codespeak.net Wed Oct 12 12:24:31 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 12:24:31 +0200 (CEST) Subject: [pypy-svn] r18458 - pypy/dist/pypy/translator/goal Message-ID: <20051012102431.5BFE127B42@code1.codespeak.net> Author: tismer Date: Wed Oct 12 12:24:25 2005 New Revision: 18458 Modified: pypy/dist/pypy/translator/goal/targetrpystonedalone.py Log: (anders, chris) added some commentary about creating stand-alone targets Modified: pypy/dist/pypy/translator/goal/targetrpystonedalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrpystonedalone.py (original) +++ pypy/dist/pypy/translator/goal/targetrpystonedalone.py Wed Oct 12 12:24:25 2005 @@ -12,3 +12,11 @@ def target(*args): return entry_point, None +""" +Why is this a stand-alone target? + +The above target specifies None as the argument types list. +This is a case treated specially in the driver.py . If the list +of input types is empty, it is meant to be a list of strings, +actually implementing argv of the executable. +""" \ No newline at end of file From tismer at codespeak.net Wed Oct 12 12:24:48 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 12:24:48 +0200 (CEST) Subject: [pypy-svn] r18459 - pypy/extradoc/sprintinfo/paris Message-ID: <20051012102448.3706827B42@code1.codespeak.net> Author: tismer Date: Wed Oct 12 12:24:47 2005 New Revision: 18459 Modified: pypy/extradoc/sprintinfo/paris/stackless-workplan.txt Log: task status update Modified: pypy/extradoc/sprintinfo/paris/stackless-workplan.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/stackless-workplan.txt (original) +++ pypy/extradoc/sprintinfo/paris/stackless-workplan.txt Wed Oct 12 12:24:47 2005 @@ -10,36 +10,40 @@ improving / refactoring ----------------------- -- move stack check out of stackless.h, let it +- (Valentino, Amaury, Armin) move stack check out of stackless.h, let it either unwind or raise RuntimeError -- always use automatic stack check detection +- (Valentino, Amaury, Armin) always use automatic stack check detection by default, and test: - test_annotated.test_recursion_detection() - pypy-c running CPython?s test_builtins.py -- make Stacklessness a translate_pypy option +- DONE (Valentino, Amaury) make Stacklessness a translate_pypy option -- add some documentation about how to make - a stand-alone target +- DONE (Anders, Chris) add some documentation about how to make + a stand-alone target (which is not obvious) + + - done by adding some comment into targetrpystonedalone.py. + Where else should we put this information? performance evaluation ---------------------- - merge stackless support and exception handling - to produce just one if clause. Use smnall test + to produce just one if clause. Use small test programs to measure the effect (see below). -- write smaller stand-alone applications +- (Anders, Chris) write smaller stand-alone applications (rpystone, richards), provide benchmark -- check the efect of false branch predicition +- check the effect of false branch predicition (if slp_frame_stack_bottom etc.) - instrument generated code to provide statistics - - do some source ordering by frequency + - do some source ordering by frequency. See thoughts about + this in the chapter to come, below. large open tasks From ac at codespeak.net Wed Oct 12 12:33:03 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 12 Oct 2005 12:33:03 +0200 (CEST) Subject: [pypy-svn] r18460 - in pypy/branch/hl-backend/pypy: annotation annotation/test rpython/ootype rpython/ootype/test Message-ID: <20051012103303.5277C27B42@code1.codespeak.net> Author: ac Date: Wed Oct 12 12:33:03 2005 New Revision: 18460 Modified: pypy/branch/hl-backend/pypy/annotation/binaryop.py pypy/branch/hl-backend/pypy/annotation/test/test_model.py pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Log: Implement unionof for SomeRef. (bert, arre) Modified: pypy/branch/hl-backend/pypy/annotation/binaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/binaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/binaryop.py Wed Oct 12 12:33:03 2005 @@ -652,7 +652,8 @@ # ____________________________________________________________ # annotation of low-level types -from pypy.annotation.model import SomePtr, ll_to_annotation, annotation_to_lltype +from pypy.annotation.model import SomePtr, SomeRef, ll_to_annotation, annotation_to_lltype +from pypy.rpython.ootype import ootype class __extend__(pairtype(SomePtr, SomePtr)): def union((p1, p2)): @@ -687,6 +688,21 @@ return pair(p2, obj).union() +class __extend__(pairtype(SomeRef, SomeRef)): + def union((r1, r2)): + common = ootype.commonBaseclass(r1.ootype, r2.ootype) + assert common is not None, 'Mixing of incompatible classes %r, %r' %(r1.ootype, r2.ootype) + return SomeRef(common) + +class __extend__(pairtype(SomeRef, SomeObject)): + def union((r, obj)): + assert False, ("mixing reference type %r with something else %r" % (r.ootype, obj)) + +class __extend__(pairtype(SomeObject, SomeRef)): + def union((obj, r2)): + return pair(r2, obj).union() + + #_________________________________________ # memory addresses Modified: pypy/branch/hl-backend/pypy/annotation/test/test_model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/test/test_model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/test/test_model.py Wed Oct 12 12:33:03 2005 @@ -173,11 +173,24 @@ py.test.raises(AssertionError, "unionof(SomeObject(), SomePtr(PS1))") def test_oo_union(): - C1 = ootype.Class("C1", None, {}) - C2 = ootype.Class("C2", C1, {}) - D = ootype.Class("D", None, {}) + C1 = ootype.Class("C1", None) + C2 = ootype.Class("C2", C1) + C3 = ootype.Class("C3", C1) + D = ootype.Class("D", None) assert unionof(SomeRef(C1), SomeRef(C1)) == SomeRef(C1) - + assert unionof(SomeRef(C1), SomeRef(C2)) == SomeRef(C1) + assert unionof(SomeRef(C2), SomeRef(C1)) == SomeRef(C1) + assert unionof(SomeRef(C2), SomeRef(C3)) == SomeRef(C1) + + assert unionof(SomeRef(C1),SomeImpossibleValue()) == SomeRef(C1) + assert unionof(SomeImpossibleValue(), SomeRef(C1)) == SomeRef(C1) + + py.test.raises(AssertionError, "unionof(SomeRef(C1), SomeRef(D))") + py.test.raises(AssertionError, "unionof(SomeRef(D), SomeRef(C1))") + py.test.raises(AssertionError, "unionof(SomeRef(C1), SomeInteger())") + py.test.raises(AssertionError, "unionof(SomeInteger(), SomeRef(C1))") + py.test.raises(AssertionError, "unionof(SomeRef(C1), SomeObject())") + py.test.raises(AssertionError, "unionof(SomeObject(), SomeRef(C1))") if __name__ == '__main__': for name, value in globals().items(): Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Wed Oct 12 12:33:03 2005 @@ -13,7 +13,8 @@ class Class(OOType): - def __init__(self, name, superclass, fields, methods={}): + def __init__(self, name, superclass, fields={}, methods={}): + self._name = name self._superclass = superclass self._methods = frozendict() @@ -30,6 +31,9 @@ def _example(self): return new(self) + def __repr__(self): + return '<%s %s>' % (self, self._name) + def _add_fields(self, fields): for name, defn in fields.iteritems(): if self._lookup(name) is not None: @@ -213,11 +217,20 @@ CLASS._add_methods(methods) def instanceof(inst, CLASS): - c = inst._TYPE + return isSubclass(inst._TYPE, CLASS) + +def isSubclass(C1, C2): + c = C1 while c is not None: - if c is CLASS: + if c is C2: return True c = c._superclass - return False +def commonBaseclass(CLASS1, CLASS2): + c = CLASS1 + while c is not None: + if isSubclass(CLASS2, c): + return c + c = c._superclass + return None Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Wed Oct 12 12:33:03 2005 @@ -175,3 +175,45 @@ d = new(D) assert d.m(d) == 9 + +def test_isSubclass(): + A = Class("A", None) + B = Class("B", A) + C = Class("C", A) + D = Class("D", C) + + assert isSubclass(A, A) + assert isSubclass(B, A) + assert isSubclass(C, A) + assert not isSubclass(A, B) + assert not isSubclass(B, C) + assert isSubclass(D, C) + assert isSubclass(D, A) + assert not isSubclass(D, B) + +def test_commonBaseclass(): + A = Class("A", None) + B = Class("B", A) + C = Class("C", A) + D = Class("D", C) + E = Class("E", None) + F = Class("F", E) + + assert commonBaseclass(A, A) == A + assert commonBaseclass(A, B) == A + assert commonBaseclass(B, A) == A + assert commonBaseclass(B, B) == B + assert commonBaseclass(B, C) == A + assert commonBaseclass(C, B) == A + assert commonBaseclass(C, A) == A + assert commonBaseclass(D, A) == A + assert commonBaseclass(D, B) == A + assert commonBaseclass(D, C) == C + assert commonBaseclass(A, D) == A + assert commonBaseclass(B, D) == A + assert commonBaseclass(C, D) == C + + assert commonBaseclass(E, A) is None + assert commonBaseclass(E, B) is None + assert commonBaseclass(F, A) is None + From dialtone at codespeak.net Wed Oct 12 12:54:27 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Wed, 12 Oct 2005 12:54:27 +0200 (CEST) Subject: [pypy-svn] r18461 - in pypy/dist/pypy: rpython rpython/module translator translator/c translator/c/src Message-ID: <20051012105427.817AF27B3F@code1.codespeak.net> Author: dialtone Date: Wed Oct 12 12:54:23 2005 New Revision: 18461 Added: pypy/dist/pypy/rpython/module/ll_stack.py Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_stackless.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/src/stack.h pypy/dist/pypy/translator/transform.py Log: generalize auto_stack_unwind to stack_check so that it can be used also when stackless mode is not enabled. It will raise a RuntimeError in that case [need test]. Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Wed Oct 12 12:54:23 2005 @@ -209,8 +209,9 @@ # stackless from pypy.rpython import objectmodel declare(objectmodel.stack_frames_depth, int, 'll_stackless/stack_frames_depth') -declare(objectmodel.stack_too_big, bool, 'll_stackless/stack_too_big') -declare(objectmodel.auto_stack_unwind, noneannotation, 'll_stackless/auto_stack_unwind') +declare(objectmodel.stack_too_big, bool, 'll_stack/too_big') +declare(objectmodel.stack_check, noneannotation, 'll_stack/check') +declare(objectmodel.stack_unwind, noneannotation, 'll_stack/unwind') # ___________________________________________________________ # the exceptions that can be implicitely raised by some operations @@ -226,4 +227,5 @@ KeyError : True, IndexError : True, AssertionError : True, + RuntimeError : True, } Added: pypy/dist/pypy/rpython/module/ll_stack.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/module/ll_stack.py Wed Oct 12 12:54:23 2005 @@ -0,0 +1,14 @@ +from pypy.rpython import objectmodel + +def ll_stack_too_big(): + return objectmodel.stack_too_big() +ll_stack_too_big.suggested_primitive = True + +def ll_stack_unwind(): + objectmodel.stack_unwind() +ll_stack_unwind.suggested_primitive = True + +def ll_stack_check(): + if ll_stack_too_big(): + ll_stack_unwind() + Modified: pypy/dist/pypy/rpython/module/ll_stackless.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_stackless.py (original) +++ pypy/dist/pypy/rpython/module/ll_stackless.py Wed Oct 12 12:54:23 2005 @@ -1,18 +1,5 @@ from pypy.rpython import objectmodel - -def ll_stackless_stack_unwind(): - pass -ll_stackless_stack_unwind.suggested_primitive = True - def ll_stackless_stack_frames_depth(): return objectmodel.stack_frames_depth() ll_stackless_stack_frames_depth.suggested_primitive = True - -def ll_stackless_stack_too_big(): - return objectmodel.stack_too_big() -ll_stackless_stack_too_big.suggested_primitive = True - -def ll_stackless_auto_stack_unwind(): - if ll_stackless_stack_too_big(): - ll_stackless_stack_unwind() Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Wed Oct 12 12:54:23 2005 @@ -47,9 +47,13 @@ def stack_too_big(): return False -def auto_stack_unwind(): +def stack_check(): if stack_too_big(): + # stack_unwind implementation is different depending on if stackless + # is enabled. If it is it unwinds the stack, otherwise it simply + # raises a RuntimeError. stack_unwind() + # ____________________________________________________________ Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Wed Oct 12 12:54:23 2005 @@ -4,7 +4,8 @@ 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, ll_strtod, ll_stackless +from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod +from pypy.rpython.module import ll_stackless, ll_stack from pypy.module.thread.rpython import ll_thread @@ -50,8 +51,8 @@ ll_thread.ll_thread_start: 'LL_thread_start', ll_thread.ll_thread_get_ident: 'LL_thread_get_ident', ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', - ll_stackless.ll_stackless_stack_unwind: 'LL_stackless_stack_unwind', - ll_stackless.ll_stackless_stack_too_big: 'LL_stackless_stack_too_big', + ll_stack.ll_stack_unwind: 'LL_stack_unwind', + ll_stack.ll_stack_too_big: 'LL_stack_too_big', } #______________________________________________________ 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 Wed Oct 12 12:54:23 2005 @@ -41,6 +41,8 @@ # include "src/ll_stackless.h" #endif +#include "src/stack.h" + #ifdef PYPY_STANDALONE # include "src/main.h" #endif Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Wed Oct 12 12:54:23 2005 @@ -5,10 +5,6 @@ # error "Stackless support: only for stand-alone executables" #endif -#ifndef MAX_STACK_SIZE -# define MAX_STACK_SIZE (1 << 20) -#endif - #define STANDALONE_ENTRY_POINT slp_standalone_entry_point @@ -32,7 +28,6 @@ extern long slp_retval_long; extern double slp_retval_double; extern void *slp_retval_voidptr; -extern char *slp_base_stack_pointer; slp_frame_t* slp_new_frame(int size, int state); long LL_stackless_stack_frames_depth(void); @@ -49,7 +44,6 @@ long slp_retval_long; double slp_retval_double; void *slp_retval_voidptr; -char *slp_base_stack_pointer = NULL; slp_frame_t* slp_new_frame(int size, int state) { @@ -100,25 +94,8 @@ } } - -char LL_stackless_stack_too_big(void) -{ - char local; - long result; - int simple_check = MAX_STACK_SIZE / 2; - /* compute the difference between local variable and - * and a stack origin pointer - */ - result = &local - slp_base_stack_pointer; - if (-simple_check < result && result < simple_check){ - return 0; - } - return 1; -} - #include "slp_state_decoding.h" - void slp_main_loop(void) { int state, signature; @@ -168,9 +145,7 @@ int slp_standalone_entry_point(RPyListOfString *argv) { - char local; int result; - slp_base_stack_pointer = &local; result = PYPY_STANDALONE(argv); if (slp_frame_stack_bottom) { slp_main_loop(); Modified: pypy/dist/pypy/translator/c/src/stack.h ============================================================================== --- pypy/dist/pypy/translator/c/src/stack.h (original) +++ pypy/dist/pypy/translator/c/src/stack.h Wed Oct 12 12:54:23 2005 @@ -2,13 +2,28 @@ /************************************************************/ /*** C header subsection: stack operations ***/ -static stack_base_pointer = NULL; +#ifndef MAX_STACK_SIZE +# define MAX_STACK_SIZE (1 << 19) +#endif + +char LL_stack_too_big(void); + +#ifndef PYPY_NOT_MAIN_FILE + +void LL_stack_unwind(void) +{ +#ifdef USE_STACKLESS + LL_stackless_stack_unwind(); +#else + RPyRaiseSimpleException(PyExc_RuntimeError, "Recursion limit exceeded"); +#endif +} char LL_stack_too_big(void) { char local; long result; - int simple_check = MAX_STACK_SIZE / 2; + static char *stack_base_pointer = NULL; if( stack_base_pointer == NULL ) stack_base_pointer = &local; @@ -16,13 +31,10 @@ /* compute the difference between local variable and * and a stack origin pointer */ - result = &local - slp_base_stack_pointer; - if (-simple_check < result && result < simple_check){ + result = &local - stack_base_pointer; + if (-MAX_STACK_SIZE < result && result < MAX_STACK_SIZE){ return 0; } return 1; } - - - - +#endif Modified: pypy/dist/pypy/translator/transform.py ============================================================================== --- pypy/dist/pypy/translator/transform.py (original) +++ pypy/dist/pypy/translator/transform.py Wed Oct 12 12:54:23 2005 @@ -14,7 +14,7 @@ from pypy.translator.annrpython import CannotSimplify from pypy.annotation import model as annmodel from pypy.annotation.specialize import MemoTable -from pypy.rpython.objectmodel import auto_stack_unwind +from pypy.rpython.objectmodel import stack_check def checkgraphs(self, blocks): seen = {} @@ -202,13 +202,13 @@ _, caller_block, _ = call_tag else: ann.warning("cycle detected but no information on where to insert " - "auto_stack_unwind()") + "stack_check()") continue - # caller block found, insert auto_stack_unwind() + # caller block found, insert stack_check() v = Variable() # push annotation on v ann.setbinding(v, annmodel.SomeImpossibleValue()) - unwind_op = SpaceOperation('simple_call', [Constant(auto_stack_unwind)], v) + unwind_op = SpaceOperation('simple_call', [Constant(stack_check)], v) caller_block.operations.insert(0, unwind_op) default_extra_passes = [ From mwh at codespeak.net Wed Oct 12 13:04:53 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 13:04:53 +0200 (CEST) Subject: [pypy-svn] r18463 - in pypy/dist/pypy/translator/asm: . test Message-ID: <20051012110453.E6C5827B43@code1.codespeak.net> Author: mwh Date: Wed Oct 12 13:04:51 2005 New Revision: 18463 Added: pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/asm/test/test_simulator.py Log: a simulator for our infinite register machine language Added: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 13:04:51 2005 @@ -0,0 +1,97 @@ +""" IRM Simulator """ +import autopath +from pypy.rpython.llinterp import LLFrame +from pypy.translator.asm.infregmachine import Instruction +from pypy.objspace.flow.model import Constant + +class Machine: + + def RunProgram(cls,commands,args=[],nreg=10,tracing=False): + #run this program + machine=Machine(nreg,args) + machine._tracing = tracing + ip=0 + while not machine.stopped(): + if ip>=len(commands): + return None + cmd=commands[ip] + if isinstance(cmd,str): + pass + elif cmd.name=='J': + ip=commands.index(cmd.arguments[0]) + elif cmd.name=='JT': + c = machine.creg() + assert c is not None + if c: + ip=commands.index(cmd.arguments[0]) + else: + machine.op(cmd.name,*cmd.arguments) + ip+=1 + return machine._retval + RunProgram=classmethod(RunProgram) + + + def __init__(self,nreg,args): + self._nreg=nreg + self._args=args + self._stopped=False + self._creg=None + self._tracing = False + self._registers=[None for x in range(nreg+1)] + + def creg(self): + return self._creg + + def registers(self): + return self._registers[1:] + + def register(self, reg): + v = self._registers[reg] + assert v is not None + return v + + def stopped(self): + return self._stopped + + def op(self,opcode,*operands): + if self._tracing: + args = [] + for arg in operands: + if isinstance(arg, int): + args.append('r%s=%s'%(arg, self._registers[arg])) + else: + args.append(arg) + print opcode, ', '.join(map(str, args)) + #will want to trap later to defer unimplemented to the LLInterpreter... + m = getattr(self,opcode,None) + if m is not None: + m(*operands) + else: + self.llop(opcode, *operands) + + def RETPYTHON(self,reg): + self._stopped=True + self._retval=self.register(reg) + + def LIA(self,destination,argindex): + self._registers[destination]=self._args[argindex.value] + + def LOAD(self,destination,immed): + self._registers[destination]=immed.value + + def MOV(self,destination,source): + self._registers[destination]=self.register(source) + + def EXCH(self,destination,source): + self._registers[destination],self._registers[source]=self.register(source),self.register(destination) + + def int_gt(self,rega,regb): + self._creg = self.register(rega) > self.register(regb) + + def llop(self, opcode, destination, *sources): + sourcevalues = [] + for r in sources: + sourcevalues.append(self.register(r)) + self._registers[destination] = LLFrame.__dict__['op_'+opcode](None, *sourcevalues) + + Added: pypy/dist/pypy/translator/asm/test/test_simulator.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/test/test_simulator.py Wed Oct 12 13:04:51 2005 @@ -0,0 +1,69 @@ +import autopath +from pypy.translator.asm.simulator import Machine +from pypy.objspace.flow.model import Constant +from pypy.translator.asm.infregmachine import Instruction + +def test_insn_by_insn(): + machine=Machine(5,[0,1111,2222,3333]) # create an IRM with 5 registers to use + + assert machine.registers()==[None,None,None,None,None] # check initialised. + + machine.op('LOAD',1,Constant(555)) + assert machine.registers()==[555,None,None,None,None] + + machine.op('LIA',2,Constant(0)) #argument 1 to register 2 + assert machine.registers()==[555,0,None,None,None] + machine.op('LIA',3,Constant(2)) #argument 3 to register 3 + assert machine.registers()==[555,0,2222,None,None] + + machine.op('MOV',2,1) + assert machine.registers()==[555,555,2222,None,None] + + machine.op('EXCH',3,2) + assert machine.registers()==[555,2222,555,None,None] + + machine.op('int_add',4,2,1) + assert machine.registers()==[555,2222,555,2222+555,None] + + try: + machine.register(5) + except AssertionError: + pass + else: + assert False, "should not get here" + + machine=Machine(3,[]) + assert machine.creg()==None + machine.LOAD(1,Constant(1)) + machine.LOAD(2,Constant(2)) + machine.int_gt(1,2) + assert machine.creg()==False + machine.int_gt(2,1) + assert machine.creg()==True + + +def test_programs(): + assert Machine.RunProgram([])==None #check our program returns None if no RETPYTHON !!! + assert Machine.RunProgram([Instruction('LOAD',(1,Constant(23))),Instruction('RETPYTHON',(1,))])==23 + + prog=[Instruction('LOAD', (1, Constant(100))), + Instruction('J', ('label',)), + Instruction('LOAD', (1, Constant(200))), + 'label', + 'label2', + Instruction('RETPYTHON', (1,))] + + assert Machine.RunProgram(prog) == 100 + + prog=[Instruction('LIA', (1, Constant(0))), + Instruction('LIA', (2, Constant(1))), + Instruction('LOAD', (3, Constant(77))), + Instruction('int_gt', (1, 2)), + Instruction('JT', ('label',)), + Instruction('LIA', (3, Constant(2))), + 'label', + Instruction('RETPYTHON', (3,))] + + assert Machine.RunProgram(prog, [1,2,3]) == 3 + assert Machine.RunProgram(prog, [2,1,3]) == 77 + From mwh at codespeak.net Wed Oct 12 14:39:39 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 14:39:39 +0200 (CEST) Subject: [pypy-svn] r18465 - pypy/dist/pypy/translator/asm Message-ID: <20051012123939.3D50627B43@code1.codespeak.net> Author: mwh Date: Wed Oct 12 14:39:37 2005 New Revision: 18465 Modified: pypy/dist/pypy/translator/asm/simulator.py Log: tweaks: trace entry and exit, implement int_lt Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 14:39:37 2005 @@ -11,6 +11,8 @@ machine=Machine(nreg,args) machine._tracing = tracing ip=0 + if tracing: + print 'args', args while not machine.stopped(): if ip>=len(commands): return None @@ -27,6 +29,8 @@ else: machine.op(cmd.name,*cmd.arguments) ip+=1 + if tracing: + print 'ret', machine._retval return machine._retval RunProgram=classmethod(RunProgram) @@ -88,6 +92,9 @@ def int_gt(self,rega,regb): self._creg = self.register(rega) > self.register(regb) + def int_lt(self,rega,regb): + self._creg = self.register(rega) < self.register(regb) + def llop(self, opcode, destination, *sources): sourcevalues = [] for r in sources: From mwh at codespeak.net Wed Oct 12 14:41:40 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 14:41:40 +0200 (CEST) Subject: [pypy-svn] r18466 - pypy/dist/pypy/translator/asm/test Message-ID: <20051012124140.C3A2C27B43@code1.codespeak.net> Author: mwh Date: Wed Oct 12 14:41:39 2005 New Revision: 18466 Modified: pypy/dist/pypy/translator/asm/test/test_asm.py Log: Run asm tests on the simulator, don't generate ppc code (for now). Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Wed Oct 12 14:41:39 2005 @@ -5,10 +5,10 @@ class TestAsm(object): def setup_class(cls): - if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': - py.test.skip('asm generation only on PPC') - - cls.processor = 'ppc' + #if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': + # py.test.skip('asm generation only on PPC') + # + #cls.processor = 'ppc' def getcompiled(self, func, view=False): t = Translator(func, simplifying=True) @@ -44,8 +44,8 @@ return x + y - 42 f = self.getcompiled(testfn)#, view=True) - assert f(2, 3) == testfn(2, 3) assert f(-2, 3) == testfn(-2, 3) + assert f(2, 5) == testfn(2, 5) def test_loop(self): def testfn(lim=int): From boria at codespeak.net Wed Oct 12 14:42:02 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Wed, 12 Oct 2005 14:42:02 +0200 (CEST) Subject: [pypy-svn] r18467 - in pypy/branch/hl-backend/pypy/rpython: . ootype/test Message-ID: <20051012124202.54E5F27B50@code1.codespeak.net> Author: boria Date: Wed Oct 12 14:41:59 2005 New Revision: 18467 Added: pypy/branch/hl-backend/pypy/rpython/typesystem.py (contents, props changed) Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py pypy/branch/hl-backend/pypy/rpython/rmodel.py pypy/branch/hl-backend/pypy/rpython/rpbc.py pypy/branch/hl-backend/pypy/rpython/rtyper.py Log: (Samuele, Boris) * Decoupling dependecies of rtyper on lltype: checkpoint. Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py Wed Oct 12 14:41:59 2005 @@ -2,6 +2,14 @@ from pypy.rpython import lltype from pypy.rpython.ootype import ootype +def specialize(f, input_types): + t = Translator(f) + t.annotate(input_types) + t.specialize(type_system="ootype") + + graph = t.flowgraphs[f] + check_only_ootype(graph) + def check_only_ootype(graph): def check_ootype(v): t = v.concretetype @@ -16,12 +24,7 @@ def test_simple(): def f(a, b): return a + b - t = Translator(f) - t.annotate([int, int]) - t.specialize(type_system="ootype") - - graph = t.flowgraphs[f] - check_only_ootype(graph) + specialize(f, [int, int]) def test_simple_call(): def f(a, b): @@ -29,11 +32,14 @@ def g(): return f(5, 3) + specialize(g, []) - t = Translator(g) - t.annotate([]) - - t.specialize(type_system="ootype") +# Adjusted from test_rclass.py +class EmptyBase(object): + pass - graph = t.flowgraphs[g] - check_only_ootype(graph) +def test_simple(): + def dummyfn(): + x = EmptyBase() + return x + specialize(dummyfn, []) Modified: pypy/branch/hl-backend/pypy/rpython/rmodel.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rmodel.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rmodel.py Wed Oct 12 14:41:59 2005 @@ -307,26 +307,8 @@ """ # __________ utilities __________ - -PyObjPtr = Ptr(PyObject) - -def getconcretetype(v): - return getattr(v, 'concretetype', PyObjPtr) - -def getfunctionptr(translator, graphfunc, getconcretetype=getconcretetype): - return getcallable(translator, graphfunc, getconcretetype, FuncType, functionptr) - -def getstaticmeth(translator, graphfunc, getconcretetype=getconcretetype): - return getcallable(translator, graphfunc, getconcretetype, ootype.StaticMethod, ootype.static_meth) - -def getcallable(translator, graphfunc, getconcretetype, typ, constr): - """Make a functionptr from the given Python function.""" - graph = translator.getflowgraph(graphfunc) - llinputs = [getconcretetype(v) for v in graph.getargs()] - lloutput = getconcretetype(graph.getreturnvar()) - FT = typ(llinputs, lloutput) - _callable = getattr(graphfunc, '_specializedversionof_', graphfunc) - return constr(FT, graphfunc.func_name, graph = graph, _callable = _callable) +from pypy.rpython.typesystem import LowLevelTypeSystem +getfunctionptr = LowLevelTypeSystem.instance.getcallable def needsgc(classdef, nogc=False): if classdef is None: Modified: pypy/branch/hl-backend/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rpbc.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rpbc.py Wed Oct 12 14:41:59 2005 @@ -345,7 +345,7 @@ def getsignature(rtyper, func): f = rtyper.getcallable(func) - graph = rtyper.deref(f).graph + graph = rtyper.type_system_deref(f).graph rinputs = [rtyper.bindingrepr(v) for v in graph.getargs()] if graph.getreturnvar() in rtyper.annotator.bindings: rresult = rtyper.bindingrepr(graph.getreturnvar()) @@ -391,7 +391,7 @@ def get_args_ret_s(self): f, _, _ = self.get_signature() - graph = self.rtyper.deref(f).graph + graph = self.rtyper.type_system_deref(f).graph rtyper = self.rtyper return [rtyper.binding(arg) for arg in graph.getargs()], rtyper.binding(graph.getreturnvar()) @@ -419,7 +419,7 @@ def rtype_simple_call(self, hop): f, rinputs, rresult = self.function_signatures().itervalues().next() - if getattr(self.rtyper.deref(f).graph, 'normalized_for_calls', False): + if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): # should not have an argument count mismatch assert len(rinputs) == hop.nb_args-1, "normalization bug" vlist = hop.inputargs(self, *rinputs) @@ -446,7 +446,7 @@ f, rinputs, rresult = self.function_signatures().itervalues().next() # the function arguments may have been normalized by normalizecalls() # already - if getattr(self.rtyper.deref(f).graph, 'normalized_for_calls', False): + if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): vlist = hop.inputargs(self, Void, *rinputs) vlist = vlist[:1] + vlist[2:] else: Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Wed Oct 12 14:41:59 2005 @@ -27,12 +27,14 @@ from pypy.translator.unsimplify import insert_empty_block from pypy.rpython.rmodel import Repr, inputconst from pypy.rpython.rmodel import TyperError, BrokenReprTyperError -from pypy.rpython.rmodel import getfunctionptr, getstaticmeth, warning +from pypy.rpython.rmodel import warning from pypy.rpython.normalizecalls import perform_normalizations from pypy.rpython.annlowlevel import annotate_lowlevel_helper from pypy.rpython.exceptiondata import ExceptionData from pypy.rpython.rmodel import log +from pypy.rpython.typesystem import LowLevelTypeSystem,\ + ObjectOrientedTypeSystem class RPythonTyper: @@ -40,9 +42,22 @@ def __init__(self, annotator, type_system="lltype"): self.annotator = annotator - if type_system not in ("lltype", "ootype"): + if type_system == "lltype": + self.type_system = LowLevelTypeSystem.instance + elif type_system == "ootype": + self.type_system = ObjectOrientedTypeSystem.instance + else: raise TyperError("Unknown type system %r!" % type_system) - self.type_system = type_system + self.type_system_deref = self.type_system.deref + + def getfunctionptr(graphfunc): + def getconcretetype(v): + return self.bindingrepr(v).lowleveltype + + return LowLevelTypeSystem.instance.getcallable( + self.annotator.translator, graphfunc, getconcretetype) + + self.getfunctionptr = getfunctionptr self.reprs = {} self._reprs_must_call_setup = [] @@ -502,32 +517,12 @@ def needs_hash_support(self, cls): return cls in self.annotator.bookkeeper.needs_hash_support - def deref(self, obj): - """Derefernce obj if it is a pointer.""" - if self.type_system == "ootype": - assert isinstance(typeOf(obj), ootype.OOType) - return obj - elif self.type_system == "lltype": - assert isinstance(typeOf(obj), Ptr) - - return obj._obj - def getcallable(self, graphfunc): - if self.type_system == "lltype": - return self.getfunctionptr(graphfunc) - - elif self.type_system == "ootype": - return self.getstaticmeth(graphfunc) - - def getstaticmeth(self, graphfunc): def getconcretetype(v): return self.bindingrepr(v).lowleveltype - return getstaticmeth(self.annotator.translator, graphfunc, getconcretetype) - def getfunctionptr(self, graphfunc): - def getconcretetype(v): - return self.bindingrepr(v).lowleveltype - return getfunctionptr(self.annotator.translator, graphfunc, getconcretetype) + return self.type_system.getcallable( + self.annotator.translator, graphfunc, getconcretetype) def annotate_helper(self, ll_function, arglltypes): """Annotate the given low-level helper function Added: pypy/branch/hl-backend/pypy/rpython/typesystem.py ============================================================================== --- (empty file) +++ pypy/branch/hl-backend/pypy/rpython/typesystem.py Wed Oct 12 14:41:59 2005 @@ -0,0 +1,54 @@ + +"""typesystem.py -- Typesystem-specific operations for RTyper.""" + +from pypy.annotation.pairtype import extendabletype + +from pypy.rpython.ootype import ootype +from pypy.rpython import lltype # FIXME lltype in separate directory + +class TypeSystem(object): + __metaclass__ = extendabletype + + def deref(self, obj): + """Dereference `obj' to concrete object.""" + raise NotImplementedError() + + def getcallable(self, translator, graphfunc, getconcretetype=None): + """Return callable given a Python function.""" + if getconcretetype is None: + getconcretetype = self.getconcretetype + graph = translator.getflowgraph(graphfunc) + llinputs = [getconcretetype(v) for v in graph.getargs()] + lloutput = getconcretetype(graph.getreturnvar()) + + typ, constr = self.callable_trait + + FT = typ(llinputs, lloutput) + _callable = getattr(graphfunc, '_specializedversionof_', graphfunc) + return constr(FT, graphfunc.func_name, graph = graph, _callable = _callable) + + def getconcretetype(self, v): + """Helper called by getcallable() to get the conrete type of a variable +in a graph.""" + raise NotImplementedError() + +class LowLevelTypeSystem(TypeSystem): + callable_trait = (lltype.FuncType, lltype.functionptr) + + def deref(self, obj): + assert isinstance(lltype.typeOf(obj), lltype.Ptr) + return obj._obj + + def getconcretetype(self, v): + return getattr(v, 'concretetype', lltype.Ptr(lltype.PyObject)) + +class ObjectOrientedTypeSystem(TypeSystem): + callable_trait = (ootype.StaticMethod, ootype.static_meth) + + def deref(self, obj): + assert isinstance(ootype.typeOf(obj), ootype.OOType) + return obj + +# All typesystems are singletons +LowLevelTypeSystem.instance = LowLevelTypeSystem() +ObjectOrientedTypeSystem.instance = ObjectOrientedTypeSystem() From mwh at codespeak.net Wed Oct 12 15:10:36 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 15:10:36 +0200 (CEST) Subject: [pypy-svn] r18468 - pypy/dist/pypy/translator/asm Message-ID: <20051012131036.A18CE27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 15:10:35 2005 New Revision: 18468 Modified: pypy/dist/pypy/translator/asm/infregmachine.py Log: oops! Modified: pypy/dist/pypy/translator/asm/infregmachine.py ============================================================================== --- pypy/dist/pypy/translator/asm/infregmachine.py (original) +++ pypy/dist/pypy/translator/asm/infregmachine.py Wed Oct 12 15:10:35 2005 @@ -1,4 +1,3 @@ -from pypy.translator.asm import regalloc class Instruction(object): @@ -51,6 +50,7 @@ print i def allocate_registers(self, nregisters): + from pypy.translator.asm import regalloc r = FiniteRegisterAssembler(nregisters) r.instructions = regalloc.regalloc(self.instructions, nregisters) # for i in r.instructions: From boria at codespeak.net Wed Oct 12 15:43:57 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Wed, 12 Oct 2005 15:43:57 +0200 (CEST) Subject: [pypy-svn] r18469 - in pypy/branch/hl-backend/pypy/rpython: . test Message-ID: <20051012134357.DC0F127B4E@code1.codespeak.net> Author: boria Date: Wed Oct 12 15:43:54 2005 New Revision: 18469 Modified: pypy/branch/hl-backend/pypy/rpython/rmodel.py pypy/branch/hl-backend/pypy/rpython/rslice.py pypy/branch/hl-backend/pypy/rpython/rtuple.py pypy/branch/hl-backend/pypy/rpython/rtyper.py pypy/branch/hl-backend/pypy/rpython/test/test_rtyper.py Log: (Samuele, Boris) * Refactor rtyper_makekey() * Fix test_rtyper.py to use helper makekey() * Checkpoint Modified: pypy/branch/hl-backend/pypy/rpython/rmodel.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rmodel.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rmodel.py Wed Oct 12 15:43:54 2005 @@ -182,8 +182,8 @@ def rtyper_makerepr(self, rtyper): r_container = rtyper.getrepr(self.s_container) return r_container.make_iterator_repr(*self.variant) - def rtyper_makekey(self): - return self.__class__, self.s_container.rtyper_makekey(), self.variant + def rtyper_makekey_ex(self, rtyper): + return self.__class__, rtyper.makekey(self.s_container), self.variant class __extend__(annmodel.SomeImpossibleValue): def rtyper_makerepr(self, rtyper): Modified: pypy/branch/hl-backend/pypy/rpython/rslice.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rslice.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rslice.py Wed Oct 12 15:43:54 2005 @@ -42,7 +42,7 @@ def rtyper_makekey(self): # use the repr itself as the key (it can only be one of the three # prebuilt reprs below). - return self.__class__, self.rtyper_makerepr(None) + return self.__class__, self.rtyper_makerepr(self) class SliceRepr(Repr): Modified: pypy/branch/hl-backend/pypy/rpython/rtuple.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtuple.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtuple.py Wed Oct 12 15:43:54 2005 @@ -22,8 +22,8 @@ def rtyper_makerepr(self, rtyper): return TupleRepr([rtyper.getrepr(s_item) for s_item in self.items]) - def rtyper_makekey(self): - keys = [s_item.rtyper_makekey() for s_item in self.items] + def rtyper_makekey_ex(self, rtyper): + keys = [rtyper.makekey(s_item) for s_item in self.items] return tuple([self.__class__]+keys) Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Wed Oct 12 15:43:54 2005 @@ -101,14 +101,22 @@ def getexceptiondata(self): return self.exceptiondata # built at the end of specialize() + def makekey(self, s_obj): + if hasattr(s_obj, "rtyper_makekey_ex"): + return s_obj.rtyper_makekey_ex(self) + return s_obj.rtyper_makekey() + + def makerepr(self, s_obj): + return s_obj.rtyper_makerepr(self) + def getrepr(self, s_obj): # s_objs are not hashable... try hard to find a unique key anyway - key = s_obj.rtyper_makekey() + key = self.makekey(s_obj) assert key[0] == s_obj.__class__ try: result = self.reprs[key] except KeyError: - result = s_obj.rtyper_makerepr(self) + result = self.makerepr(s_obj) assert not isinstance(result.lowleveltype, ContainerType), ( "missing a Ptr in the type specification " "of %s:\n%r" % (s_obj, result.lowleveltype)) Modified: pypy/branch/hl-backend/pypy/rpython/test/test_rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/test/test_rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/test/test_rtyper.py Wed Oct 12 15:43:54 2005 @@ -1,5 +1,6 @@ from pypy.annotation import model as annmodel from pypy.translator.translator import Translator +from pypy.translator import annrpython from pypy.rpython.lltype import * from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.rtyper import RPythonTyper @@ -19,8 +20,9 @@ annmodel.SomeInteger())) stup2 = annmodel.SomeTuple((annmodel.SomeString(), annmodel.SomeInteger())) - key1 = stup1.rtyper_makekey() - key2 = stup2.rtyper_makekey() + rtyper = RPythonTyper(annrpython.RPythonAnnotator(None)) + key1 = rtyper.makekey(stup1) + key2 = rtyper.makekey(stup2) assert key1 != key2 def test_slice_reprkeys(): From dialtone at codespeak.net Wed Oct 12 15:44:39 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Wed, 12 Oct 2005 15:44:39 +0200 (CEST) Subject: [pypy-svn] r18470 - in pypy/dist/pypy/translator: . c/test Message-ID: <20051012134439.EE6F627B4E@code1.codespeak.net> Author: dialtone Date: Wed Oct 12 15:44:38 2005 New Revision: 18470 Modified: pypy/dist/pypy/translator/c/test/test_standalone.py pypy/dist/pypy/translator/transform.py Log: (valentino, afa, armin) activate stack_check and refactor a test to not randomly fail Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Wed Oct 12 15:44:38 2005 @@ -15,14 +15,14 @@ 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() + cbuilder.compile() data = cbuilder.cmdexec('hi there') assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') @@ -100,10 +100,22 @@ def test_stack_too_big(): + def f1(): + return stack_too_big() + def f2(): + return lst[1]() + def f3(): + return lst[2]() + def f4(): + return lst[3]() + def f5(): + return lst[4]() + lst = [None,f1,f2,f3,f4,f5] + def f(n): - if stack_too_big(): + if lst[5](): return n - return f(n+1) + return f(n)+1 def fn(): return f(0) @@ -111,7 +123,7 @@ assert int(data.strip()) > 500 - + def wrap_stackless_function(fn, stackcheck=False): def entry_point(argv): os.write(1, str(fn())+"\n") @@ -120,13 +132,11 @@ t = Translator(entry_point) s_list_of_strings = SomeList(ListDef(None, SomeString())) ann = t.annotate([s_list_of_strings]) - if stackcheck: - insert_stackcheck(ann) t.specialize() cbuilder = t.cbuilder(standalone=True) cbuilder.stackless = True cbuilder.generate_source() - cbuilder.compile() + cbuilder.compile() return cbuilder.cmdexec('') def test_stack_unwind(): @@ -137,11 +147,10 @@ data = wrap_stackless_function(f) assert int(data.strip()) == 42 - def test_auto_stack_unwind(): def f(n): if n == 1: - return 1 + return 1 return (n+f(n-1)) % 1291 def fn(): Modified: pypy/dist/pypy/translator/transform.py ============================================================================== --- pypy/dist/pypy/translator/transform.py (original) +++ pypy/dist/pypy/translator/transform.py Wed Oct 12 15:44:38 2005 @@ -222,6 +222,7 @@ # modified by t.simplify() after it had been annotated. if block_subset is None: block_subset = fully_annotated_blocks(ann) + insert_stackcheck(ann) if not isinstance(block_subset, dict): block_subset = dict.fromkeys(block_subset) if ann.translator: From ericvrp at codespeak.net Wed Oct 12 15:51:54 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 12 Oct 2005 15:51:54 +0200 (CEST) Subject: [pypy-svn] r18471 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051012135154.5058D27B4E@code1.codespeak.net> Author: ericvrp Date: Wed Oct 12 15:51:52 2005 New Revision: 18471 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/structnode.py pypy/dist/pypy/translator/js/test/test_genllvm1.py Log: working on (Gc)Structs Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Wed Oct 12 15:51:52 2005 @@ -166,7 +166,7 @@ else: s.append("\\%02x" % ord(c)) - r = 'c"%s"' % "".join(s) + r = '"%s"' % "".join(s) return item_length, r class VoidArrayNode(ConstantLLVMNode): Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Wed Oct 12 15:51:52 2005 @@ -71,29 +71,39 @@ #self.llvm("implementation", 0) pass - def br_uncond(self, block): - self.append('prevblock = ' + str(self._currentblock)) + def _goto_block(self, block, indentation_level=4): if block == self._currentblock + 1: self._skip_closeblock = True else: - self.append('block = ' + str(block)) + self.append('block = ' + str(block), indentation_level) + self.append('break', indentation_level) - def br(self, cond, block_false, block_true): - self.append('prevblock = ' + str(self._currentblock)) + def _phi(self, targetblock, exit, indentation_level=4): + #self.comment('target.inputargs=%s, args=%s, targetblock=%d' % (exit.target.inputargs, exit.args, targetblock), indentation_level) + for i, exitarg in enumerate(exit.args): + dest = str(exit.target.inputargs[i]) + src = str(exitarg) + if src == 'False': + src = 'false' + elif src == 'True': + src = 'true' + if dest != src: + self.append('%s = %s' % (dest, src), indentation_level) + + def br_uncond(self, block, exit): + self._phi(block, exit) + self._goto_block(block) + self._skip_closeblock = True + + def br(self, cond, block_false, exit_false, block_true, exit_true): self.append('if (%s) {' % cond) - if block_true == self._currentblock + 1: - self._skip_closeblock = True - else: - self.append('block = ' + str(block_true), 5) - self.append('break', 5) - if block_false == self._currentblock + 1: - self._skip_closeblock = True - else: - self.append('} else {') - self.append('block = ' + str(block_false), 5) - self.append('break', 5) + self._phi(block_true, exit_true, 5) + self._goto_block(block_true, 5) + self.append('} else {') + self._phi(block_false, exit_false, 5) + self._goto_block(block_false, 5) self.append('}') - self.comment('block = %s ? %d : %d' % (cond, block_true, block_false)) + self._skip_closeblock = True def switch(self, intty, cond, defaultdest, value_label): labels = '' @@ -108,6 +118,10 @@ self.blocks = blocks usedvars = {} #XXX could probably be limited to inputvars for block in blocks: + if block != blocks[0]: #don't double startblock inputargs + for inputarg in block.inputargs: + targetvar = self.js.db.repr_arg(inputarg) + usedvars[targetvar] = True for op in block.operations: targetvar = self.js.db.repr_arg(op.result) usedvars[targetvar] = True @@ -130,36 +144,6 @@ self.append("return " + ref) self._skip_closeblock = True - def phi(self, targetvar, type_, refs, blocks): - assert refs and len(refs) == len(blocks), "phi node requires blocks" - mergelist = ", ".join( - ["[%s, %s]" % item - for item in zip(refs, blocks)]) - s = "%s = phi %s %s" % (targetvar, type_, mergelist) - self.llvm(s) - - all_refs_identical = True - for ref in refs: - if ref != refs[0]: - all_refs_identical = False - break - if all_refs_identical: - if targetvar != refs[0]: - self.append('%s = %s' % (targetvar, refs[0])) - else: - if len(blocks) == 1: - self.append('%s = %s' % (targetvar, refs[i])) - else: - n = 0 - for i, block in enumerate(blocks): - if targetvar != refs[i]: - if n > 0: - s = 'else ' - else: - s = '' - self.append('%sif (prevblock == %d) %s = %s' % (s, block, targetvar, refs[i])) - n += 1 - def binaryop(self, name, targetvar, type_, ref1, ref2): self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Wed Oct 12 15:51:52 2005 @@ -260,7 +260,8 @@ type_ = lltype.typeOf(value) if isinstance(type_, lltype.Primitive): repr = self.primitive_to_str(type_, value) - return None, "%s %s" % (self.repr_type(type_), repr) + return None, repr + #return None, "%s %s" % (self.repr_type(type_), repr) elif isinstance(type_, lltype.Ptr): toptr = self.repr_type(type_) Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Wed Oct 12 15:51:52 2005 @@ -42,14 +42,15 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = self.make_ref('pypy_', value.graph.name) + pypy_prefix = '' #pypy_ + self.ref = self.make_ref(pypy_prefix, value.graph.name) self.graph = value.graph self.db.genllvm.exceptionpolicy.transform(self.db.translator, self.graph) #remove_exception_mallocs(self.db.translator, self.graph, self.ref) #merge_mallocs(self.db.translator, self.graph, self.ref) - remove_double_links(self.db.translator, self.graph) + #remove_double_links(self.db.translator, self.graph) def __str__(self): return "" %(self.ref,) @@ -145,30 +146,30 @@ return self.ref + "(%s)" % ", ".join(inputargs) def write_block(self, codewriter, block): - self.write_block_phi_nodes(codewriter, block) + #self.write_block_phi_nodes(codewriter, block) self.write_block_operations(codewriter, block) self.write_block_branches(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) - inputargtypes = self.db.repr_arg_type_multi(block.inputargs) - for i, (arg, type_) in enumerate(zip(inputargs, inputargtypes)): - names = self.db.repr_arg_multi([link.args[i] for link in entrylinks]) - blocknames = [self.blockindex[link.prevblock] for link in entrylinks] - for i, link in enumerate(entrylinks): #XXX refactor into a transformation - if link.prevblock.exitswitch == Constant(last_exception) and \ - link.prevblock.exits[0].target != block: - blocknames[i] += '_exception_found_branchto_' + self.blockindex[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": - codewriter.phi(arg, type_, names, blocknames) + #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) + # inputargtypes = self.db.repr_arg_type_multi(block.inputargs) + # for i, (arg, type_) in enumerate(zip(inputargs, inputargtypes)): + # names = self.db.repr_arg_multi([link.args[i] for link in entrylinks]) + # blocknames = [self.blockindex[link.prevblock] for link in entrylinks] + # for i, link in enumerate(entrylinks): #XXX refactor into a transformation + # if link.prevblock.exitswitch == Constant(last_exception) and \ + # link.prevblock.exits[0].target != block: + # blocknames[i] += '_exception_found_branchto_' + self.blockindex[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": + # 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) @@ -176,11 +177,12 @@ #codewriter.comment('FuncNode(ConstantLLVMNode) *last_exception* write_block_branches @%s@' % str(block.exits)) return if len(block.exits) == 1: - codewriter.br_uncond(self.blockindex[block.exits[0].target]) + codewriter.br_uncond(self.blockindex[block.exits[0].target], block.exits[0]) elif len(block.exits) == 2: cond = self.db.repr_arg(block.exitswitch) - codewriter.br(cond, self.blockindex[block.exits[0].target], - self.blockindex[block.exits[1].target]) + codewriter.br(cond, + self.blockindex[block.exits[0].target], block.exits[0], + self.blockindex[block.exits[1].target], block.exits[1]) def write_block_operations(self, codewriter, block): opwriter = OpWriter(self.db, codewriter, self, block) @@ -212,7 +214,7 @@ def write_returnblock(self, codewriter, block): assert len(block.inputargs) == 1 - self.write_block_phi_nodes(codewriter, block) + #self.write_block_phi_nodes(codewriter, block) inputargtype = self.db.repr_arg_type(block.inputargs[0]) inputarg = self.db.repr_arg(block.inputargs[0]) codewriter.ret(inputargtype, inputarg) Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Wed Oct 12 15:51:52 2005 @@ -105,13 +105,15 @@ for typ_decl in self.db.getnodes(): typ_decl.writeimpl(codewriter) + pypy_prefix = '' #pypy_ + #codewriter.append(self.exceptionpolicy.llvmcode(self.entrynode)) # ## XXX we need to create our own main() that calls the actual entry_point function - #if entryfunc_name == 'pypy_entry_point': #XXX just to get on with translate_pypy + #if entryfunc_name == pypy_prefix + '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 + #elif entryfunc_name == pypy_prefix + 'main_noargs': #XXX just to get on with bpnn & richards # extfuncnode.ExternalFuncNode.used_external_functions['%main_noargs'] = True # #for f in support_functions: @@ -134,7 +136,7 @@ graph = self.db.obj2node[entry_point].graph startblock = graph.startblock args = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)]) - self.wrappertemplate = "load('%s'); print(pypy_%s(%%s))" % (self.filename, graph.name) + self.wrappertemplate = "load('%s'); print(%s%s(%%s))" % (self.filename, pypy_prefix, graph.name) #codewriter.newline() #codewriter.comment("Wrapper code for the Javascript CLI", 0) Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Wed Oct 12 15:51:52 2005 @@ -147,9 +147,16 @@ def constantvalue(self): """ Returns the constant representation for this node. """ - values = self._getvalues() - all_values = ",\n ".join(values) - return "%s {\n %s\n }\n" % (self.get_typerepr(), all_values) + vars = [] + for i, value in enumerate(self._getvalues()): + name = self._get_types[i][0] + var = (name, str(value)) + vars.append(var) + return "(%s)" % ", ".join(["{%s:%s}" % var for var in vars]) + + #values = self._getvalues() + #all_values = ",\n ".join(values) + #return "%s {\n %s\n }\n" % (self.get_typerepr(), all_values) class StructVarsizeNode(StructNode): Modified: pypy/dist/pypy/translator/js/test/test_genllvm1.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_genllvm1.py (original) +++ pypy/dist/pypy/translator/js/test/test_genllvm1.py Wed Oct 12 15:51:52 2005 @@ -28,7 +28,7 @@ def test_ackermann(self): f = compile_function(llvmsnippet.ackermann, [int, int]) - for i in range(10): + for i in range(7): #>7 js error: too much recursion?!? assert f(0, i) == i + 1 assert f(1, i) == i + 2 assert f(2, i) == 2 * i + 3 From mwh at codespeak.net Wed Oct 12 15:56:40 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 15:56:40 +0200 (CEST) Subject: [pypy-svn] r18472 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051012135640.9D88E27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 15:56:39 2005 New Revision: 18472 Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Log: stomp a variable we save rather than one we don't. Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/func_builder.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Wed Oct 12 15:56:39 2005 @@ -7,14 +7,14 @@ code.lwz(rD, r4, 12 + 4*argi) if typecode == 'i': code.load_word(r0, lookup("PyInt_Type")) - code.lwz(r15, rD, 4) # XXX ick! - code.cmpw(r0, r15) + code.lwz(r31, rD, 4) # XXX ick! + code.cmpw(r0, r31) code.bne("argserror") code.lwz(rD, rD, 8) elif typecode == 'f': code.load_word(r0, lookup("PyFloat_Type")) - code.lwz(r15, rD, 4) - code.cmpw(r0, r15) + code.lwz(r31, rD, 4) + code.cmpw(r0, r31) code.bne("argserror") code.lfd(rD-2, rD, 8) elif typecode != "O": From mwh at codespeak.net Wed Oct 12 15:57:21 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 15:57:21 +0200 (CEST) Subject: [pypy-svn] r18473 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051012135721.01CF327B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 15:57:19 2005 New Revision: 18473 Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Log: delete trailing whitespace -- mainly to say "register! register! i meant register in the last check in message!" :) Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/func_builder.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Wed Oct 12 15:57:19 2005 @@ -47,7 +47,7 @@ load_arg(ourcode, 1, signature[1]) ourcode.bl(FAST_ENTRY_LABEL) - + if retcode == 'i': s = lookup("PyInt_FromLong") ourcode.load_word(r0, s) @@ -96,7 +96,7 @@ return r def wrap(funcname, retcode, signature): - + argcount = len(signature) ourcode = MyPPCAssembler() @@ -118,11 +118,11 @@ if argcount > 1: load_arg(ourcode, 1, signature[1]) - + ourcode.load_word(r0, lookup(funcname)) ourcode.mtctr(r0) ourcode.bctrl() - + if retcode == 'i': s = lookup("PyInt_FromLong") ourcode.load_word(r0, s) From boria at codespeak.net Wed Oct 12 15:58:05 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Wed, 12 Oct 2005 15:58:05 +0200 (CEST) Subject: [pypy-svn] r18474 - pypy/branch/hl-backend/pypy/rpython Message-ID: <20051012135805.13AAD27B4E@code1.codespeak.net> Author: boria Date: Wed Oct 12 15:58:03 2005 New Revision: 18474 Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py pypy/branch/hl-backend/pypy/rpython/typesystem.py Log: (Samuele, Boris) * Beginnings of multiple dispatch on type system and annotation. Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Wed Oct 12 15:58:03 2005 @@ -102,12 +102,10 @@ return self.exceptiondata # built at the end of specialize() def makekey(self, s_obj): - if hasattr(s_obj, "rtyper_makekey_ex"): - return s_obj.rtyper_makekey_ex(self) - return s_obj.rtyper_makekey() + return pair(self.type_system, s_obj).rtyper_makekey(self) def makerepr(self, s_obj): - return s_obj.rtyper_makerepr(self) + return pair(self.type_system, s_obj).rtyper_makerepr(self) def getrepr(self, s_obj): # s_objs are not hashable... try hard to find a unique key anyway Modified: pypy/branch/hl-backend/pypy/rpython/typesystem.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/typesystem.py (original) +++ pypy/branch/hl-backend/pypy/rpython/typesystem.py Wed Oct 12 15:58:03 2005 @@ -52,3 +52,19 @@ # All typesystems are singletons LowLevelTypeSystem.instance = LowLevelTypeSystem() ObjectOrientedTypeSystem.instance = ObjectOrientedTypeSystem() + +# Multiple dispatch on type system and high-level annotation + +from pypy.annotation.pairtype import pairtype +from pypy.annotation.model import SomeObject + +class __extend__(pairtype(TypeSystem, SomeObject)): + def rtyper_makerepr((ts, s_obj), rtyper): + return s_obj.rtyper_makerepr(rtyper) + + def rtyper_makekey((ts, s_obj), rtyper): + if hasattr(s_obj, "rtyper_makekey_ex"): + return s_obj.rtyper_makekey_ex(rtyper) + return s_obj.rtyper_makekey() + + From mwh at codespeak.net Wed Oct 12 16:01:09 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 16:01:09 +0200 (CEST) Subject: [pypy-svn] r18475 - pypy/dist/pypy/translator/asm Message-ID: <20051012140109.1213127B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 16:01:07 2005 New Revision: 18475 Added: pypy/dist/pypy/translator/asm/regalloc.py Log: the simplest possible register allocator: one that barfs if we use too many registers. Added: pypy/dist/pypy/translator/asm/regalloc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/regalloc.py Wed Oct 12 16:01:07 2005 @@ -0,0 +1,14 @@ + +def regalloc(insns, nregisters): +# from pypy.translator.asm.infregmachine import Instruction + + maxregs = 0 + + for insn in insns: + if isinstance(insn, str): + continue + maxregs = max(insn.registers_used() + [0]) + + if maxregs < 30: + return insns[:] + From mwh at codespeak.net Wed Oct 12 16:02:07 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 16:02:07 +0200 (CEST) Subject: [pypy-svn] r18476 - in pypy/dist/pypy/translator: . asm asm/test Message-ID: <20051012140207.A3FF727B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 16:02:05 2005 New Revision: 18476 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/infregmachine.py pypy/dist/pypy/translator/asm/test/test_asm.py pypy/dist/pypy/translator/translator.py Log: run tests both as our infinite register machine language and as ppc machine code (when possible). Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 16:02:05 2005 @@ -2,6 +2,7 @@ from pypy.objspace.flow.model import traverse, Block, Variable, Constant from pypy.translator.asm import infregmachine from pypy.rpython.lltype import Signed +from pypy.translator.asm.simulator import Machine #Available Machine code targets (processor+operating system) TARGET_UNKNOWN=0 @@ -33,7 +34,7 @@ from pypy.translator.asm.i386gen.i386_assembler import make_func -def genasm(translator): +def genasm(translator, processor): f = translator.entrypoint @@ -48,10 +49,19 @@ g = FuncGenerator(graph) g.gencode() -# g.assembler.dump() -# finreg = g.assembler.allocate_registers(5) - return make_func(finreg.assemble(), 'i', 'i'*len(graph.startblock.inputargs)) + if processor == 'virt': + def r(*args): + return Machine.RunProgram(g.assembler.instructions, + args, + 1000, + tracing=True) + + return r + elif processor == 'ppc': + fin = g.assembler.allocate_registers(30) + return make_func(fin.assemble(), 'i', + 'i'*len(graph.startblock.inputargs)) class FuncGenerator(object): Modified: pypy/dist/pypy/translator/asm/infregmachine.py ============================================================================== --- pypy/dist/pypy/translator/asm/infregmachine.py (original) +++ pypy/dist/pypy/translator/asm/infregmachine.py Wed Oct 12 16:02:05 2005 @@ -33,6 +33,19 @@ args = ', '.join(map(c, self.arguments)) return '%-30s'%(' %-10s %s'%(self.name, args),) +class Program(object): + # approximately a list of Instructions, but with sprinkles + # not used yet. + + def __init__(self, insns): + self.insns = insns + + def iterinsns(self): + for insn in self.insns: + if isinstance(ins, str): + continue + yield insn + class Assembler(object): def __init__(self): self.instructions = [] @@ -53,9 +66,6 @@ from pypy.translator.asm import regalloc r = FiniteRegisterAssembler(nregisters) r.instructions = regalloc.regalloc(self.instructions, nregisters) -# for i in r.instructions: -# if not isinstance(i, str): # labels -# assert max(i.registers_used() + [0]) < nregisters r.dump() return r Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Wed Oct 12 16:02:05 2005 @@ -4,11 +4,7 @@ class TestAsm(object): - def setup_class(cls): - #if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': - # py.test.skip('asm generation only on PPC') - # - #cls.processor = 'ppc' + processor = 'virt' def getcompiled(self, func, view=False): t = Translator(func, simplifying=True) @@ -61,4 +57,13 @@ assert f(10) == testfn(10) assert f(100) == testfn(100) assert f(1000) == testfn(1000) - + +class TestAsmPPC(TestAsm): + + processor = 'ppc' + + def setup_class(cls): + if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': + py.test.skip('asm generation only on PPC') + + Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Wed Oct 12 16:02:05 2005 @@ -327,11 +327,11 @@ self.frozen = True return genllvm.genllvm(self, really_compile=really_compile, standalone=standalone, optimize=optimize, exe_name=exe_name, gcpolicy=gcpolicy) - def asmcompile(self, processor='ppc'): + def asmcompile(self, processor='virt'): from pypy.translator.asm import genasm - assert processor == 'ppc', 'only ppc asm-generation supported for now' + assert processor in ['ppc', 'virt'] assert self.rtyper is not None, 'must specialize' - return genasm.genasm(self) + return genasm.genasm(self, processor) def call(self, *args): """Calls underlying Python function.""" From tismer at codespeak.net Wed Oct 12 16:02:25 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 16:02:25 +0200 (CEST) Subject: [pypy-svn] r18477 - pypy/dist/pypy/translator/goal Message-ID: <20051012140225.546A327B4E@code1.codespeak.net> Author: tismer Date: Wed Oct 12 16:02:24 2005 New Revision: 18477 Modified: pypy/dist/pypy/translator/goal/targetrpystonedalone.py Log: supports rpystone and richards, now. moving on to use this for small-program benchmarking. Modified: pypy/dist/pypy/translator/goal/targetrpystonedalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrpystonedalone.py (original) +++ pypy/dist/pypy/translator/goal/targetrpystonedalone.py Wed Oct 12 16:02:24 2005 @@ -1,11 +1,63 @@ import os, sys from pypy.translator.test import rpystone +from pypy.translator.goal import richards +import pypy.interpreter.gateway # needed before sys, order of imports !!! +from pypy.module.sys.version import svn_revision # __________ Entry point __________ +VERSION = svn_revision() + +# note that we have %f but no length specifiers in RPython + +def pystones_main(loops): + benchtime, stones = rpystone.pystones(abs(loops)) + s = '' # annotator happiness + if loops >= 0: + s = ("RPystone(%s) time for %d passes = %f" % + (VERSION, loops, benchtime) + '\n' + ( + "This machine benchmarks at %f pystones/second" % stones)) + os.write(1, s) + +def richards_main(iterations): + s = "Richards benchmark (RPython) starting...\n" + os.write(1, s) + result, startTime, endTime = richards.entry_point(iterations) + if not result: + os.write(2, "Incorrect results!\n") + return + os.write(1, "finished.\n") + total_s = endTime - startTime + avg = total_s * 1000 / iterations + os.write(1, "Total time for %d iterations: %f secs\n" %(iterations, total_s)) + os.write(1, "Average time per iteration: %f ms\n" %(avg)) + +DEF_PYSTONE = 10000000 +DEF_RICHARDS = 1000 + def entry_point(argv): - count = rpystone.pystones(20000000) - return count + proc = pystones_main + default = DEF_PYSTONE + n = 0 + for s in argv[1:]: + s = s.lower() + if 'pystone'.startswith(s): + proc = pystones_main + default = DEF_PYSTONE + elif 'richards'.startswith(s): + proc = richards_main + default = DEF_RICHARDS + else: + try: + n = abs(int(s)) + except ValueError: + os.write(2, '%s is neither a valid option (pystone, richards)' + ' nor an integer\n') + return 1 + if not n: + n = default + proc(n) + return 0 # _____ Define and setup target ___ From arigo at codespeak.net Wed Oct 12 16:14:38 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 12 Oct 2005 16:14:38 +0200 (CEST) Subject: [pypy-svn] r18478 - in pypy/dist/pypy: objspace/flow objspace/flow/test rpython/test Message-ID: <20051012141438.3D26227B4E@code1.codespeak.net> Author: arigo Date: Wed Oct 12 16:14:32 2005 New Revision: 18478 Modified: pypy/dist/pypy/objspace/flow/objspace.py pypy/dist/pypy/objspace/flow/test/test_objspace.py pypy/dist/pypy/rpython/test/test_rstr.py Log: Let the flow object space consider that the built-in int() can raise ValueError implicitely. We already have support for this in the rtyper. Modified: pypy/dist/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/objspace.py (original) +++ pypy/dist/pypy/objspace/flow/objspace.py Wed Oct 12 16:14:32 2005 @@ -395,7 +395,7 @@ types.ClassType, types.TypeType)) and c.__module__ in ['__builtin__', 'exceptions']): - exceptions = None + exceptions = implicit_exceptions.get(c, None) self.handle_implicit_exceptions(exceptions) return w_res @@ -434,7 +434,9 @@ op_appendices[_exc] = _name del _name, _exc -implicit_exceptions = {} +implicit_exceptions = { + int: [ValueError], # built-ins that can always raise exceptions + } def _add_exceptions(names, exc): for name in names.split(): Modified: pypy/dist/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/dist/pypy/objspace/flow/test/test_objspace.py Wed Oct 12 16:14:32 2005 @@ -267,7 +267,7 @@ def implicitException_int_and_id(x): try: return int(x) + id(x) - except ValueError: # not captured by the flow graph! + except TypeError: # not captured by the flow graph! return 0 def test_implicitException_int_and_id(self): 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 Oct 12 16:14:32 2005 @@ -472,6 +472,17 @@ res = interpret(fn, [i, j]) assert res == expected +def test_int_valueerror(): + s1 = ['42g', '?'] + def fn(i): + try: + return int(s1[i]) + except ValueError: + return -654 + res = interpret(fn, [0]) + assert res == -654 + res = interpret(fn, [1]) + assert res == -654 def test_char_mul_n(): def f(c, n): From ac at codespeak.net Wed Oct 12 16:27:53 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 12 Oct 2005 16:27:53 +0200 (CEST) Subject: [pypy-svn] r18479 - in pypy/branch/hl-backend/pypy: annotation rpython/ootype rpython/ootype/test Message-ID: <20051012142753.5985827B4E@code1.codespeak.net> Author: ac Date: Wed Oct 12 16:27:53 2005 New Revision: 18479 Modified: pypy/branch/hl-backend/pypy/annotation/bookkeeper.py pypy/branch/hl-backend/pypy/annotation/builtin.py pypy/branch/hl-backend/pypy/annotation/model.py pypy/branch/hl-backend/pypy/annotation/unaryop.py pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py Log: (bert, arre) Teach the annotator about the null function, methods and static methods. Modified: pypy/branch/hl-backend/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/bookkeeper.py (original) +++ pypy/branch/hl-backend/pypy/annotation/bookkeeper.py Wed Oct 12 16:27:53 2005 @@ -353,6 +353,8 @@ elif isinstance(x, lladdress.address): assert x is lladdress.NULL result= SomeAddress(is_null=True) + elif isinstance(x, ootype._static_meth): + result = SomeStaticMeth(ootype.typeOf(x)) elif callable(x) or isinstance(x, staticmethod): # XXX # maybe 'x' is a method bound to a not-yet-frozen cache? # fun fun fun. Modified: pypy/branch/hl-backend/pypy/annotation/builtin.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/builtin.py (original) +++ pypy/branch/hl-backend/pypy/annotation/builtin.py Wed Oct 12 16:27:53 2005 @@ -374,6 +374,12 @@ r = SomeRef(ootype.typeOf(i)) return r +def null(C): + assert C.is_constant() + i = ootype.null(C.const) + r = SomeRef(ootype.typeOf(i)) + return r + def instanceof(c, C): assert C.is_constant() assert isinstance(C.const, ootype.Class) @@ -381,6 +387,7 @@ BUILTIN_ANALYZERS[ootype.instanceof] = instanceof BUILTIN_ANALYZERS[ootype.new] = new +BUILTIN_ANALYZERS[ootype.null] = null #________________________________ # non-gc objects Modified: pypy/branch/hl-backend/pypy/annotation/model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/model.py Wed Oct 12 16:27:53 2005 @@ -435,7 +435,15 @@ def __init__(self, ootype): self.ootype = ootype +class SomeBoundMeth(SomeObject): + def __init__(self, ootype, name): + self.ootype = ootype + self.name = name +class SomeStaticMeth(SomeObject): + def __init__(self, method): + self.method = method + from pypy.rpython import lltype from pypy.rpython.ootype import ootype Modified: pypy/branch/hl-backend/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/unaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/unaryop.py Wed Oct 12 16:27:53 2005 @@ -566,7 +566,9 @@ # annotation of low-level types -from pypy.annotation.model import SomePtr, SomeRef, ll_to_annotation, annotation_to_lltype +from pypy.annotation.model import SomePtr, SomeRef, SomeBoundMeth, SomeStaticMeth +from pypy.annotation.model import ll_to_annotation, annotation_to_lltype + class __extend__(SomePtr): def getattr(p, s_attr): @@ -592,12 +594,28 @@ def is_true(p): return SomeBool() +from pypy.rpython.ootype import ootype class __extend__(SomeRef): - def getattr(p, s_attr): - assert s_attr.is_constant(), "getattr on ref %r with non-constant field-name" % p.ootype - v = getattr(p.ootype._example(), s_attr.const) + def getattr(r, s_attr): + assert s_attr.is_constant(), "getattr on ref %r with non-constant field-name" % r.ootype + v = getattr(r.ootype._example(), s_attr.const) + if isinstance(v, ootype._bound_meth): + return SomeBoundMeth(r.ootype, s_attr.const) + return ll_to_annotation(v) + +class __extend__(SomeBoundMeth): + def simple_call(m, *args_s): + llargs = [annotation_to_lltype(arg_s)._example() for arg_s in args_s] + inst = m.ootype._example() + v = getattr(inst, m.name)(*llargs) return ll_to_annotation(v) +class __extend__(SomeStaticMeth): + def simple_call(m, *args_s): + llargs = [annotation_to_lltype(arg_s)._example() for arg_s in args_s] + smeth = m.method._example() + v = smeth(*llargs) + return ll_to_annotation(v) #_________________________________________ # memory addresses @@ -611,3 +629,4 @@ assert s_attr.const in lladdress.supported_access_types return SomeTypedAddressAccess( lladdress.supported_access_types[s_attr.const]) + Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Wed Oct 12 16:27:53 2005 @@ -100,6 +100,10 @@ self.ARGS = tuple(args) self.RESULT = result + def _example(self): + _retval = self.RESULT._example() + return _static_meth(self, _callable=lambda *args: _retval) + class Meth(StaticMethod): def __init__(self, args, result): @@ -190,11 +194,14 @@ return _bound_meth(inst, self) class _bound_meth(object): - def __init__(self, inst, meth): + #self._TYPE = self self.inst = inst self.meth = meth + #def _example(self): + # return self + def __call__(self, *args): return self.meth._checkargs(args)(self.inst, *args) Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py Wed Oct 12 16:27:53 2005 @@ -8,10 +8,10 @@ C = Class("test", None, {'a': Signed}) def oof(): - c = new(C) - return c.a + c = new(C) + return c.a - a = RPythonAnnotator() + a = RPythonAnnotator() s = a.build_types(oof, []) #a.translator.view() @@ -21,11 +21,78 @@ C = Class("test", None, {'a': Signed}) def oof(): - c = new(C) - return instanceof(c, C) + c = new(C) + return instanceof(c, C) - a = RPythonAnnotator() + a = RPythonAnnotator() s = a.build_types(oof, []) #a.translator.view() assert s.knowntype == bool + +def test_simple_null(): + C = Class("test", None, {'a': Signed}) + + def oof(): + c = null(C) + return c + + a = RPythonAnnotator() + s = a.build_types(oof, []) + #a.translator.view() + + assert s == annmodel.SomeRef(C) + +def test_method(): + C = Class("test", None, {"a": (Signed, 3)}) + + M = Meth([C], Signed) + def m_(self, other): + return self.a + other.a + m = meth(M, _name="m", _callable=m_) + + addMethods(C, {"m": m}) + + def oof(): + c = new(C) + return c.m(c) + + a = RPythonAnnotator() + s = a.build_types(oof, []) + # a.translator.view() + + assert s.knowntype == int + +def test_unionof(): + C1 = Class("C1", None) + C2 = Class("C2", C1) + C3 = Class("C3", C1) + + def oof(f): + if f: + c = new(C2) + else: + c = new(C3) + return c + + a = RPythonAnnotator() + s = a.build_types(oof, [bool]) + #a.translator.view() + + assert s == annmodel.SomeRef(C1) + +def test_static_method(): + F = StaticMethod([Signed, Signed], Signed) + def f_(a, b): + return a+b + f = static_meth(F, "f", _callable=f_) + + def oof(): + return f(2,3) + + a = RPythonAnnotator() + s = a.build_types(oof, []) + #a.translator.view() + + assert s.knowntype = int + From arigo at codespeak.net Wed Oct 12 16:35:35 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 12 Oct 2005 16:35:35 +0200 (CEST) Subject: [pypy-svn] r18480 - pypy/dist/pypy/objspace/flow Message-ID: <20051012143535.DC52127B4E@code1.codespeak.net> Author: arigo Date: Wed Oct 12 16:35:33 2005 New Revision: 18480 Modified: pypy/dist/pypy/objspace/flow/model.py Log: oups. Modified: pypy/dist/pypy/objspace/flow/model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/model.py (original) +++ pypy/dist/pypy/objspace/flow/model.py Wed Oct 12 16:35:33 2005 @@ -256,6 +256,7 @@ name = '_' + name name = self.namesdict.setdefault(name, (name, 0))[0] self._name = name + self._nr = -1 def set_name_from(self, v): # this is for SSI_to_SSA only which should not know about internals From mwh at codespeak.net Wed Oct 12 16:38:01 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 16:38:01 +0200 (CEST) Subject: [pypy-svn] r18481 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051012143801.3114227B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 16:37:59 2005 New Revision: 18481 Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Log: Allow callers of make_func to reserve some space on the stack. Modified: pypy/dist/pypy/translator/asm/ppcgen/func_builder.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/func_builder.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/func_builder.py Wed Oct 12 16:37:59 2005 @@ -22,16 +22,18 @@ FAST_ENTRY_LABEL = "FAST-ENTRY-LABEL" -def make_func(code, retcode, signature): +def make_func(code, retcode, signature, localwords=0): """code shouldn't contain prologue/epilogue (or touch r31)""" + stacksize = 80 + 4*localwords + argcount = len(signature) ourcode = MyPPCAssembler() ourcode.mflr(r0) ourcode.stmw(r31, r1, -4) ourcode.stw(r0, r1, 8) - ourcode.stwu(r1, r1, -80) + ourcode.stwu(r1, r1, -stacksize) ourcode.lwz(r3, r4, 8) ourcode.cmpwi(r3, argcount) @@ -60,8 +62,8 @@ ourcode.bctrl() ourcode.label("epilogue") - ourcode.lwz(r0, r1, 88) - ourcode.addi(r1, r1, 80) + ourcode.lwz(r0, r1, stacksize + 8) + ourcode.addi(r1, r1, stacksize) ourcode.mtlr(r0) ourcode.lmw(r31, r1, -4) ourcode.blr() From afa at codespeak.net Wed Oct 12 16:38:21 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 16:38:21 +0200 (CEST) Subject: [pypy-svn] r18482 - in pypy/dist/pypy: rpython translator translator/c/src translator/c/test Message-ID: <20051012143821.0BA7027B4E@code1.codespeak.net> Author: afa Date: Wed Oct 12 16:38:14 2005 New Revision: 18482 Modified: pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/src/support.h pypy/dist/pypy/translator/c/test/test_annotated.py pypy/dist/pypy/translator/c/test/test_typed.py pypy/dist/pypy/translator/transform.py Log: (valentino, afa): corrections for stack checks + minor compilation warnings fixes Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Wed Oct 12 16:38:14 2005 @@ -24,6 +24,7 @@ from pypy.rpython.lltype import attachRuntimeTypeInfo, Primitive from pypy.tool.sourcetools import func_with_new_name, valid_identifier from pypy.translator.unsimplify import insert_empty_block +from pypy.translator.transform import insert_stackcheck from pypy.rpython.rmodel import Repr, inputconst from pypy.rpython.rmodel import TyperError, BrokenReprTyperError from pypy.rpython.rmodel import getfunctionptr, warning @@ -109,7 +110,9 @@ self.crash_on_first_typeerror = crash_on_first_typeerror # specialize depends on annotator simplifications if not dont_simplify_again: + insert_stackcheck(self.annotator) self.annotator.simplify() + # first make sure that all functions called in a group have exactly # the same signature, by hacking their flow graphs if needed perform_normalizations(self) Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Wed Oct 12 16:38:14 2005 @@ -156,5 +156,5 @@ #endif /* PYPY_NOT_MAIN_FILE */ -#endif USE_STACKLESS +#endif /* USE_STACKLESS */ 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 Wed Oct 12 16:38:14 2005 @@ -34,8 +34,13 @@ PyObject* PyList_Pack(int n, ...); PyObject* PyDict_Pack(int n, ...); PyObject* PyTuple_Pack(int n, ...); +#if PY_VERSION_HEX >= 0x02030000 /* 2.3 */ +# define PyObject_GetItem1 PyObject_GetItem +# define PyObject_SetItem1 PyObject_SetItem +#else PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index); PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v); +#endif PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...); PyObject* decode_arg(PyObject* fname, int position, PyObject* name, PyObject* vargs, PyObject* vkwds, PyObject* def); @@ -168,10 +173,7 @@ } #endif -#if PY_VERSION_HEX >= 0x02030000 /* 2.3 */ -# define PyObject_GetItem1 PyObject_GetItem -# define PyObject_SetItem1 PyObject_SetItem -#else +#if PY_VERSION_HEX < 0x02030000 /* 2.3 */ /* for Python 2.2 only */ PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index) { Modified: pypy/dist/pypy/translator/c/test/test_annotated.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_annotated.py (original) +++ pypy/dist/pypy/translator/c/test/test_annotated.py Wed Oct 12 16:38:14 2005 @@ -166,14 +166,3 @@ fn = self.getcompiled(f) assert fn(-4.5) == 92.125 assert fn(4.5) == 90.125 - - def test_recursion_detection(self): - def f(n=int, accum=int): - if n == 0: - return accum - else: - return f(n-1, accum*n) - fn = self.getcompiled(f) - assert fn(7, 1) == 5040 - py.test.skip("recursion detection: in-progress") - py.test.raises(RuntimeError, fn, -1, 0) 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 Wed Oct 12 16:38:14 2005 @@ -1,5 +1,6 @@ import autopath import sys +import py from py.test import raises from pypy.translator.translator import Translator from pypy.translator.test import snippet @@ -398,3 +399,13 @@ f = self.getcompiled(fn) for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]: assert f(*args) == intmask(fn(*args)) + + def test_recursion_detection(self): + def f(n=int, accum=int): + if n == 0: + return accum + else: + return f(n-1, accum*n) + fn = self.getcompiled(f) + assert fn(7, 1) == 5040 + py.test.raises(RuntimeError, fn, -1, 0) Modified: pypy/dist/pypy/translator/transform.py ============================================================================== --- pypy/dist/pypy/translator/transform.py (original) +++ pypy/dist/pypy/translator/transform.py Wed Oct 12 16:38:14 2005 @@ -222,7 +222,6 @@ # modified by t.simplify() after it had been annotated. if block_subset is None: block_subset = fully_annotated_blocks(ann) - insert_stackcheck(ann) if not isinstance(block_subset, dict): block_subset = dict.fromkeys(block_subset) if ann.translator: From mwh at codespeak.net Wed Oct 12 16:39:06 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 16:39:06 +0200 (CEST) Subject: [pypy-svn] r18483 - in pypy/dist/pypy/translator/asm: . i386gen Message-ID: <20051012143906.C45CA27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 16:39:04 2005 New Revision: 18483 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/i386gen/ (props changed) pypy/dist/pypy/translator/asm/infregmachine.py (contents, props changed) pypy/dist/pypy/translator/asm/regalloc.py (contents, props changed) Log: use the second most straightforward register allocator: one that spills all the time. also, a little fixeol-ing Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 16:39:04 2005 @@ -59,9 +59,16 @@ return r elif processor == 'ppc': + maxregs = 0 + for insn in g.assembler.instructions: + if isinstance(insn, str): + continue + for r in insn.registers_used(): + maxregs = max(r, maxregs) fin = g.assembler.allocate_registers(30) return make_func(fin.assemble(), 'i', - 'i'*len(graph.startblock.inputargs)) + 'i'*len(graph.startblock.inputargs), + maxregs) class FuncGenerator(object): Modified: pypy/dist/pypy/translator/asm/infregmachine.py ============================================================================== --- pypy/dist/pypy/translator/asm/infregmachine.py (original) +++ pypy/dist/pypy/translator/asm/infregmachine.py Wed Oct 12 16:39:04 2005 @@ -127,6 +127,12 @@ A.mr(dest + 2, src + 2) def EXCH(self, A, a, b): - A.xor(a, a, b) - A.xor(b, b, a) - A.xor(a, a, b) + A.xor(a+2, a+2, b+2) + A.xor(b+2, b+2, a+2) + A.xor(a+2, a+2, b+2) + + def STORESTACK(self, A, s, v): + A.stw(v+2, 1, 24+4*s.value) + + def LOADSTACK(self, A, v, s): + A.lwz(v+2, 1, 24+4*s.value) Modified: pypy/dist/pypy/translator/asm/regalloc.py ============================================================================== --- pypy/dist/pypy/translator/asm/regalloc.py (original) +++ pypy/dist/pypy/translator/asm/regalloc.py Wed Oct 12 16:39:04 2005 @@ -1,14 +1,24 @@ +from pypy.objspace.flow.model import Constant def regalloc(insns, nregisters): -# from pypy.translator.asm.infregmachine import Instruction + from pypy.translator.asm.infregmachine import Instruction - maxregs = 0 + output = [] for insn in insns: if isinstance(insn, str): + output.append(insn) continue - maxregs = max(insn.registers_used() + [0]) - - if maxregs < 30: - return insns[:] - + thismap = {} + for i, r in enumerate(insn.registers_used()): + if r not in thismap: + if insn.name != 'LIA': + output.append(Instruction('LOADSTACK', (i+1, Constant(r)))) + thismap[r] = i+1 + else: + thismap[r] = r + output.append(insn.renumber(thismap)) + for r, i in thismap.items(): + output.append(Instruction('STORESTACK', (Constant(r), i))) + + return output From mwh at codespeak.net Wed Oct 12 17:00:48 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 17:00:48 +0200 (CEST) Subject: [pypy-svn] r18484 - in pypy/dist/pypy/translator/asm: . ppc Message-ID: <20051012150048.58EC027B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 17:00:46 2005 New Revision: 18484 Added: pypy/dist/pypy/translator/asm/ppc/ pypy/dist/pypy/translator/asm/ppc/__init__.py pypy/dist/pypy/translator/asm/ppc/codegen.py Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/infregmachine.py Log: move some data around Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 17:00:46 2005 @@ -59,16 +59,8 @@ return r elif processor == 'ppc': - maxregs = 0 - for insn in g.assembler.instructions: - if isinstance(insn, str): - continue - for r in insn.registers_used(): - maxregs = max(r, maxregs) - fin = g.assembler.allocate_registers(30) - return make_func(fin.assemble(), 'i', - 'i'*len(graph.startblock.inputargs), - maxregs) + from pypy.translator.asm.ppc import codegen + return codegen.make_native_code(graph, g.assembler.instructions) class FuncGenerator(object): Modified: pypy/dist/pypy/translator/asm/infregmachine.py ============================================================================== --- pypy/dist/pypy/translator/asm/infregmachine.py (original) +++ pypy/dist/pypy/translator/asm/infregmachine.py Wed Oct 12 17:00:46 2005 @@ -61,78 +61,3 @@ if isinstance(i, str): i += ':' print i - - def allocate_registers(self, nregisters): - from pypy.translator.asm import regalloc - r = FiniteRegisterAssembler(nregisters) - r.instructions = regalloc.regalloc(self.instructions, nregisters) - r.dump() - return r - -class FiniteRegisterAssembler(Assembler): - def __init__(self, nregisters): - Assembler.__init__(self) - self.nregisters = nregisters - - def assemble(self): - from pypy.translator.asm.ppcgen import ppc_assembler - A = ppc_assembler.PPCAssembler() - - for i in self.instructions: - if isinstance(i, str): - A.label(i) - continue - - getattr(self, i.name)(A, *i.arguments) - - return A - - def LIA(self, A, dest, argindex): - assert dest + 2 == argindex.value + 3 - - def LOAD(self, A, dest, value): - value = value.value - assert isinstance(value, int) - assert -30000 < value < 30000 - A.li(dest + 2, value) - - def int_add(self, A, dest, a, b): - A.add(dest + 2, a + 2, b + 2) - - def int_sub(self, A, dest, a, b): - A.sub(dest + 2, a + 2, b + 2) - - def int_mul(self, A, dest, a, b): - A.mullw(dest + 2, a + 2, b + 2) - - def int_gt(self, A, a, b): - A.cmpw(a + 2, b + 2) - A.crmove(0, 1) - - def int_lt(self, A, a, b): - A.cmpw(a + 2, b + 2) - - def JT(self, A, branch): - # should be "A.bt(BI=0, BD=branch)" but this crashes. - A.blt(branch) - - def J(self, A, branch): - A.b(branch) - - def RETPYTHON(self, A, reg): - A.mr(3, reg + 2) - A.blr() - - def MOV(self, A, dest, src): - A.mr(dest + 2, src + 2) - - def EXCH(self, A, a, b): - A.xor(a+2, a+2, b+2) - A.xor(b+2, b+2, a+2) - A.xor(a+2, a+2, b+2) - - def STORESTACK(self, A, s, v): - A.stw(v+2, 1, 24+4*s.value) - - def LOADSTACK(self, A, v, s): - A.lwz(v+2, 1, 24+4*s.value) Added: pypy/dist/pypy/translator/asm/ppc/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppc/__init__.py Wed Oct 12 17:00:46 2005 @@ -0,0 +1 @@ +# nowt Added: pypy/dist/pypy/translator/asm/ppc/codegen.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/ppc/codegen.py Wed Oct 12 17:00:46 2005 @@ -0,0 +1,86 @@ + +def make_native_code(graph, infreginsns): + from pypy.translator.asm.ppcgen.func_builder import make_func + maxregs = 0 + for insn in infreginsns: + if isinstance(insn, str): + continue + for r in insn.registers_used(): + maxregs = max(r, maxregs) + + from pypy.translator.asm import regalloc + + insns = regalloc.regalloc(infreginsns, 30) + + codegen = PPCCodeGen() + + return make_func(codegen.assemble(insns), 'i', + 'i'*len(graph.startblock.inputargs), + maxregs) + + +class PPCCodeGen(object): + + def assemble(self, insns): + from pypy.translator.asm.ppcgen import ppc_assembler + A = ppc_assembler.PPCAssembler() + + for i in insns: + if isinstance(i, str): + A.label(i) + continue + + getattr(self, i.name)(A, *i.arguments) + + return A + + def LIA(self, A, dest, argindex): + assert dest + 2 == argindex.value + 3 + + def LOAD(self, A, dest, value): + value = value.value + assert isinstance(value, int) + assert -30000 < value < 30000 + A.li(dest + 2, value) + + def int_add(self, A, dest, a, b): + A.add(dest + 2, a + 2, b + 2) + + def int_sub(self, A, dest, a, b): + A.sub(dest + 2, a + 2, b + 2) + + def int_mul(self, A, dest, a, b): + A.mullw(dest + 2, a + 2, b + 2) + + def int_gt(self, A, a, b): + A.cmpw(a + 2, b + 2) + A.crmove(0, 1) + + def int_lt(self, A, a, b): + A.cmpw(a + 2, b + 2) + + def JT(self, A, branch): + # should be "A.bt(BI=0, BD=branch)" but this crashes. + A.blt(branch) + + def J(self, A, branch): + A.b(branch) + + def RETPYTHON(self, A, reg): + A.mr(3, reg + 2) + A.blr() + + def MOV(self, A, dest, src): + A.mr(dest + 2, src + 2) + + def EXCH(self, A, a, b): + A.xor(a+2, a+2, b+2) + A.xor(b+2, b+2, a+2) + A.xor(a+2, a+2, b+2) + + def STORESTACK(self, A, s, v): + A.stw(v+2, 1, 24+4*s.value) + + def LOADSTACK(self, A, v, s): + A.lwz(v+2, 1, 24+4*s.value) + From ericvrp at codespeak.net Wed Oct 12 17:07:03 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 12 Oct 2005 17:07:03 +0200 (CEST) Subject: [pypy-svn] r18485 - pypy/dist/pypy/translator/js Message-ID: <20051012150703.AEAB127B4E@code1.codespeak.net> Author: ericvrp Date: Wed Oct 12 17:07:02 2005 New Revision: 18485 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/structnode.py Log: * remove string null termination * fix incorrect struct instance syntax Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Wed Oct 12 17:07:02 2005 @@ -156,9 +156,10 @@ 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 + #don't force null termination anymore! + #if item_length == 0 or items[-1] != chr(0): + # items = items + [chr(0)] + # item_length += 1 s = [] for c in items: if ord(c) in StrArrayNode.printables: Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Wed Oct 12 17:07:02 2005 @@ -83,7 +83,7 @@ self.db = db self.value = value self.structtype = self.value._TYPE - prefix = 'structinstance.' + prefix = 'structinstance_' name = str(value).split()[1] self.ref = self.make_ref(prefix, name) self._get_ref_cache = None @@ -152,7 +152,7 @@ name = self._get_types[i][0] var = (name, str(value)) vars.append(var) - return "(%s)" % ", ".join(["{%s:%s}" % var for var in vars]) + return "({%s})" % ", ".join(["%s:%s" % var for var in vars]) #values = self._getvalues() #all_values = ",\n ".join(values) From mwh at codespeak.net Wed Oct 12 17:10:34 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 17:10:34 +0200 (CEST) Subject: [pypy-svn] r18486 - in pypy/dist/pypy/translator/asm: . ppc test Message-ID: <20051012151034.0834F27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 17:10:31 2005 New Revision: 18486 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/ppc/codegen.py pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: new test and stuff needed to implement it. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 17:10:31 2005 @@ -137,7 +137,8 @@ assert block.exitswitch is not None falselink, truelink = block.exits lastop = block.operations[-1] - assert lastop.opname in ['int_gt', 'int_lt', 'int_ge'] + assert lastop.opname in ['int_gt', 'int_lt', 'int_ge', + 'int_eq'] A.emit(lastop.opname, *map(self.reg, lastop.args)) b = self.blockname() A.emit('JT', b) Modified: pypy/dist/pypy/translator/asm/ppc/codegen.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppc/codegen.py (original) +++ pypy/dist/pypy/translator/asm/ppc/codegen.py Wed Oct 12 17:10:31 2005 @@ -52,6 +52,12 @@ def int_mul(self, A, dest, a, b): A.mullw(dest + 2, a + 2, b + 2) + def int_mod(self, A, dest, a, b): + dest += 2; a += 2; b += 2 + A.divw(dest, a, b) + A.mullw(dest, dest, b) + A.subf(dest, dest, a) + def int_gt(self, A, a, b): A.cmpw(a + 2, b + 2) A.crmove(0, 1) @@ -59,6 +65,10 @@ def int_lt(self, A, a, b): A.cmpw(a + 2, b + 2) + def int_eq(self, A, a, b): + A.cmpw(a + 2, b + 2) + A.crmove(0, 2) + def JT(self, A, branch): # should be "A.bt(BI=0, BD=branch)" but this crashes. A.blt(branch) Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 17:10:31 2005 @@ -95,6 +95,9 @@ def int_lt(self,rega,regb): self._creg = self.register(rega) < self.register(regb) + def int_eq(self,rega,regb): + self._creg = self.register(rega) == self.register(regb) + def llop(self, opcode, destination, *sources): sourcevalues = [] for r in sources: Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Wed Oct 12 17:10:31 2005 @@ -58,6 +58,20 @@ assert f(100) == testfn(100) assert f(1000) == testfn(1000) + def test_factor(self): + def factor(n=int): + i = 2 + while i < n: + if n % i == 0: + return i + i += 1 + return i + f = self.getcompiled(factor) + + assert f(25) == 5 + assert f(27) == 3 + assert f(29) == 29 + class TestAsmPPC(TestAsm): processor = 'ppc' From tismer at codespeak.net Wed Oct 12 17:22:42 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 17:22:42 +0200 (CEST) Subject: [pypy-svn] r18487 - pypy/dist/pypy/translator/c Message-ID: <20051012152242.7C1C027B4E@code1.codespeak.net> Author: tismer Date: Wed Oct 12 17:22:41 2005 New Revision: 18487 Modified: pypy/dist/pypy/translator/c/genc.py Log: disabled splitting for small files,again (sorry about the check-in) XXX find out whether we are standalone and use this as criteria Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Wed Oct 12 17:22:41 2005 @@ -158,7 +158,7 @@ funcnodes.append(node) else: othernodes.append(node) - if 1 or len(funcnodes) >= SPLIT_CRITERIA:##!! + if len(funcnodes) >= SPLIT_CRITERIA: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes From mwh at codespeak.net Wed Oct 12 17:38:06 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 17:38:06 +0200 (CEST) Subject: [pypy-svn] r18490 - in pypy/dist/pypy/translator/asm: . ppc test Message-ID: <20051012153806.14EBA27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 17:38:03 2005 New Revision: 18490 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/ppc/codegen.py pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: another test, some more operations and some rearrangement Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 17:38:03 2005 @@ -138,7 +138,7 @@ falselink, truelink = block.exits lastop = block.operations[-1] assert lastop.opname in ['int_gt', 'int_lt', 'int_ge', - 'int_eq'] + 'int_eq', 'int_le'] A.emit(lastop.opname, *map(self.reg, lastop.args)) b = self.blockname() A.emit('JT', b) Modified: pypy/dist/pypy/translator/asm/ppc/codegen.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppc/codegen.py (original) +++ pypy/dist/pypy/translator/asm/ppc/codegen.py Wed Oct 12 17:38:03 2005 @@ -43,6 +43,32 @@ assert -30000 < value < 30000 A.li(dest + 2, value) + def JT(self, A, branch): + # should be "A.bt(BI=0, BD=branch)" but this crashes. + A.blt(branch) + + def J(self, A, branch): + A.b(branch) + + def RETPYTHON(self, A, reg): + A.mr(3, reg + 2) + A.blr() + + def MOV(self, A, dest, src): + A.mr(dest + 2, src + 2) + + def EXCH(self, A, a, b): + A.xor(a+2, a+2, b+2) + A.xor(b+2, b+2, a+2) + A.xor(a+2, a+2, b+2) + + def STORESTACK(self, A, s, v): + A.stw(v+2, 1, 24+4*s.value) + + def LOADSTACK(self, A, v, s): + A.lwz(v+2, 1, 24+4*s.value) + + def int_add(self, A, dest, a, b): A.add(dest + 2, a + 2, b + 2) @@ -58,6 +84,11 @@ A.mullw(dest, dest, b) A.subf(dest, dest, a) + + def int_and(self, A, dest, a, b): + A.and_(dest + 2, a + 2, b + 2) + + def int_gt(self, A, a, b): A.cmpw(a + 2, b + 2) A.crmove(0, 1) @@ -68,29 +99,7 @@ def int_eq(self, A, a, b): A.cmpw(a + 2, b + 2) A.crmove(0, 2) - - def JT(self, A, branch): - # should be "A.bt(BI=0, BD=branch)" but this crashes. - A.blt(branch) - - def J(self, A, branch): - A.b(branch) - - def RETPYTHON(self, A, reg): - A.mr(3, reg + 2) - A.blr() - - def MOV(self, A, dest, src): - A.mr(dest + 2, src + 2) - - def EXCH(self, A, a, b): - A.xor(a+2, a+2, b+2) - A.xor(b+2, b+2, a+2) - A.xor(a+2, a+2, b+2) - def STORESTACK(self, A, s, v): - A.stw(v+2, 1, 24+4*s.value) - - def LOADSTACK(self, A, v, s): - A.lwz(v+2, 1, 24+4*s.value) - + def int_le(self, A, a, b): + A.cmpw(a + 2, b + 2) + A.cror(0, 0, 2) Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 17:38:03 2005 @@ -98,6 +98,9 @@ def int_eq(self,rega,regb): self._creg = self.register(rega) == self.register(regb) + def int_le(self,rega,regb): + self._creg = self.register(rega) <= self.register(regb) + def llop(self, opcode, destination, *sources): sourcevalues = [] for r in sources: Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Wed Oct 12 17:38:03 2005 @@ -70,8 +70,27 @@ assert f(25) == 5 assert f(27) == 3 + assert f(17*13) == 13 assert f(29) == 29 + def test_from_psyco(self): + def f1(n=int): + "Arbitrary test function." + i = 0 + x = 1 + while i Author: mwh Date: Wed Oct 12 17:47:18 2005 New Revision: 18491 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/ppc/codegen.py pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: test all integer comparisons. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 17:47:18 2005 @@ -138,7 +138,7 @@ falselink, truelink = block.exits lastop = block.operations[-1] assert lastop.opname in ['int_gt', 'int_lt', 'int_ge', - 'int_eq', 'int_le'] + 'int_eq', 'int_le', 'int_ne'] A.emit(lastop.opname, *map(self.reg, lastop.args)) b = self.blockname() A.emit('JT', b) Modified: pypy/dist/pypy/translator/asm/ppc/codegen.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppc/codegen.py (original) +++ pypy/dist/pypy/translator/asm/ppc/codegen.py Wed Oct 12 17:47:18 2005 @@ -96,10 +96,18 @@ def int_lt(self, A, a, b): A.cmpw(a + 2, b + 2) - def int_eq(self, A, a, b): + def int_ge(self, A, a, b): A.cmpw(a + 2, b + 2) - A.crmove(0, 2) + A.cror(0, 1, 2) def int_le(self, A, a, b): A.cmpw(a + 2, b + 2) A.cror(0, 0, 2) + + def int_eq(self, A, a, b): + A.cmpw(a + 2, b + 2) + A.crmove(0, 2) + + def int_ne(self, A, a, b): + A.cmpw(a + 2, b + 2) + A.cror(0, 0, 1) Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 17:47:18 2005 @@ -89,18 +89,26 @@ def EXCH(self,destination,source): self._registers[destination],self._registers[source]=self.register(source),self.register(destination) + def int_gt(self,rega,regb): self._creg = self.register(rega) > self.register(regb) def int_lt(self,rega,regb): self._creg = self.register(rega) < self.register(regb) - def int_eq(self,rega,regb): - self._creg = self.register(rega) == self.register(regb) + def int_ge(self,rega,regb): + self._creg = self.register(rega) >= self.register(regb) def int_le(self,rega,regb): self._creg = self.register(rega) <= self.register(regb) + def int_eq(self,rega,regb): + self._creg = self.register(rega) == self.register(regb) + + def int_ne(self,rega,regb): + self._creg = self.register(rega) != self.register(regb) + + def llop(self, opcode, destination, *sources): sourcevalues = [] for r in sources: Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Wed Oct 12 17:47:18 2005 @@ -89,7 +89,25 @@ f = self.getcompiled(f1) assert f(10) == f1(10) - + def test_comparisons(self): + def f(x=int): + if x == 0: + return 0 + elif x > 10: + return 10 + elif x >= 5: + return 5 + elif x < -10: + return -10 + elif x <= -5: + return -5 + elif x != 1: + return 1 + else: + return x + g = self.getcompiled(f) + for i in range(-20, 20): + assert g(i) == f(i) class TestAsmPPC(TestAsm): From afa at codespeak.net Wed Oct 12 17:50:19 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 17:50:19 +0200 (CEST) Subject: [pypy-svn] r18492 - pypy/dist/pypy/translator/c/test Message-ID: <20051012155019.BDE1E27B4E@code1.codespeak.net> Author: afa Date: Wed Oct 12 17:50:16 2005 New Revision: 18492 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: (valentino, afa): Skip a test that does not work reliably on win32 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 Oct 12 17:50:16 2005 @@ -18,6 +18,7 @@ # note: clock synchronizes itself! def test_time_clock(): + py.test.skip("time.clock like it is used here is not reliable") def does_stuff(): return time.clock() f1 = compile(does_stuff, []) From mwh at codespeak.net Wed Oct 12 18:15:31 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 18:15:31 +0200 (CEST) Subject: [pypy-svn] r18493 - pypy/dist/pypy/translator/asm/test Message-ID: <20051012161531.DB12D27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 18:15:30 2005 New Revision: 18493 Modified: pypy/dist/pypy/translator/asm/test/test_asm.py Log: this would be a nice test one day. Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Wed Oct 12 18:15:30 2005 @@ -1,4 +1,5 @@ from pypy.translator.translator import Translator +from pypy.rpython.rarithmetic import ovfcheck import py import os @@ -109,6 +110,17 @@ for i in range(-20, 20): assert g(i) == f(i) + def dont_test_overflow(self): + def f(x=int, y=int): + try: + return ovfcheck(x*y) + except OverflowError: + return 0 + g = self.getcompiled(f, view=True) + assert f(3, 4) == g(3, 4) + big = 1000000000 + assert f(big, big) == g(big, big) + class TestAsmPPC(TestAsm): processor = 'ppc' From mwh at codespeak.net Wed Oct 12 18:21:46 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 18:21:46 +0200 (CEST) Subject: [pypy-svn] r18494 - in pypy/dist/pypy/translator/asm: . test Message-ID: <20051012162146.8198127B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 18:21:43 2005 New Revision: 18494 Modified: pypy/dist/pypy/translator/asm/regmap.py pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/asm/test/test_simulator.py Log: (AndrewT MH) Fixed register allocation and merged into simulator with translator Modified: pypy/dist/pypy/translator/asm/regmap.py ============================================================================== --- pypy/dist/pypy/translator/asm/regmap.py (original) +++ pypy/dist/pypy/translator/asm/regmap.py Wed Oct 12 18:21:43 2005 @@ -1,12 +1,24 @@ +""" +To convert our IRM to an FRM machine, we must perform some swapping of the registers. This is in effect +'paging', we are only allowed to perform XCHG operations on the slow (memory) registers, while we can do +anything with our fast (CPU registers). +There are various algorithms available, including the Linear Scan Algorithm (google this), but for now we +have decided to implement a simple, but (hopefully) reasonably effective last-recently-used algortithm. -import random -random.seed(101) -n=10 -m=5 -initial=[ random.randint(1,m) for x in range(n)] +Regardless of the swap algorithm , at each stage we must keep track of which IRM register is held in which +FRM register. Our original test-suite simply gave the register usages, and checked the swap/usage sequence. + +We need to rebuild the suite, checking the register map at EACH stage of the process. Fiddly, but important! + +We need some notation: + +IRMxxx denotes an Infinite Register Machine that will use at most xxx registers + +FRMxxx.yyy denotes a finite-register machine, with xxx fast registers, and a total of yyy registers. + +""" -#now recode to n-register machine def remap(regs,n): return regs @@ -36,6 +48,7 @@ print re return re +import sys def remap(regs,n): pipe=[] @@ -47,21 +60,72 @@ if goingin>n: goingout=pipe[-1] re.append((goingin,goingout)) + + old2new[goingin]=goingout old2new[goingout]=goingin + val=goingout + #having swapped, if we have any stray mapping,remove it. + else: val=goingin pipe=[val]+pipe re.append(val) + + if old2new.get(reg,reg)!=val: + print regs + print old2new + print pipe + print re + sys.exit(1) if len(pipe)>n: - pipe.pop() + popped=pipe.pop() #this value fell out of the pipe + + print re + return re + + +def remap(regs,n): + pipe=[] + old2new=range(len(regs)+1) + re=[] + for reg in regs: + goingin=old2new[reg] + #print reg,pipe,old2new + if goingin>n: + goingout=pipe[-1] + re.append((goingin,goingout)) + + old2new[goingout],old2new[goingin] = old2new[goingin],old2new[goingout] + print '>>>',old2new + #old2new[goingin]=goingout + #old2new[goingout]=goingin + + val=goingout + #having swapped, if we have any stray mapping,remove it. + + else: + val=goingin + pipe=[val]+pipe + re.append(val) + + + if len(pipe)>n: + popped=pipe.pop() #this value fell out of the pipe + + print re + print range(20) + print old2new return re assert remap([1,2,3],3)==[1,2,3] assert remap([1,2,3],2)==[1,2,(3,1),1] + + assert remap([1,2,3,1],2)==[1,2,(3,1),1,(3,2),2] + assert remap([1,2,3,4,2],2)==[1,2,(3,1),1,(4,2),2,(4,1),1] assert remap([1,2,3,2,1],2)==[1, 2, (3, 1), 1, 2, (3, 1), 1] @@ -69,6 +133,108 @@ assert remap([1,2,3,4,5,4,3,2,1],10)==[1,2,3,4,5,4,3,2,1] assert remap([1,2,3,4,5,4,3,2,1],3)==[1,2,3,(4,1),1,(5,2),2,1,3,(5,2),2,(4,1),1] +#assert remap([1,2,4,3,4,1,5,3,5,6,1,2,8,7,6,8,9,7,9,10,1,2],5)==7 #this is a real-world example for PowerPC + + +class Machine: + def __init__(self,nreg,regtot=100): + self._nreg=nreg + self._pipe=[] + self._regtot=regtot + self._old2new=range(0,regtot+1) #this must be as big as the total number of registers+1 (we start at index 1) + + def regIRM(self,regIRM): + ins=[] + reg=regIRM + goingin=self._old2new[reg] + if goingin>self._nreg: + goingout=self._pipe[-1] + ins.append((goingin,goingout)) + self._old2new[goingout],self._old2new[goingin] = self._old2new[goingin],self._old2new[goingout] + val=goingout + else: + val=goingin + self._pipe=[val]+self._pipe + ins.append(val) + + if len(self._pipe)>self._nreg: + self._pipe.pop() #this value fell out of the pipe + + self._lastFRMUSed=val + return ins + + + def lastFRMUsed(self): + return self._lastFRMUsed + + def map(self): + import operator + """answer a map IRM notation -> current FRM notation""" + map={} + for reg in range(1,self._regtot+1): + map[reg]=operator.indexOf(self._old2new,reg) + return map + + def identityMap(self): + """check that the current map is the identity map""" + map=self.map() + for reg in range(1,self._regtot+1): + if map[reg]!=reg: + return False + return True + +print '\n\n NEW SUITE \n\n' + +machine=Machine(1,1) #create an FRM1 using an IRM1 translation +assert machine.identityMap() #check our registers +assert machine.regIRM(1)==[1] # use IRM register 1,check emitted code is just usage of register 1 +assert machine.map()=={1:1} + +machine=Machine(1,2) # FRM1 using IRM2 translation +assert machine.regIRM(1)==[1] #use IRM1.1 ,no need to swap +assert machine.map()=={1:1,2:2} #identity mapping is preserved. + +assert machine.regIRM(2)==[(2,1),1] #use IRM1.2. We will need a swap +assert machine.map()=={1:2,2:1} #now we have non-trival permutation. +assert not machine.identityMap() #also, show it is not the identity map.(have to test this too!) + +assert machine.regIRM(1)==[(2,1),1] #use IRM1.1 again (this time we should get a swap) +assert machine.map()=={1:1,2:2} #and recover the identity map + +#now a more involved example + +machine=Machine(3,5) #2 real registers, from a machine which uses 5 registers +assert machine.identityMap() +assert machine.regIRM(1)==[1] +assert machine.regIRM(2)==[2] +assert machine.regIRM(3)==[3] +assert machine.regIRM(1)==[1] +assert machine.regIRM(4)==[(4,2),2] +assert machine.regIRM(2)==[(4,3),3] +assert machine.map()=={1:1,2:3,3:4,4:2,5:5} + +machine=Machine(3,5) #3 real registers, from a machine which uses 5 registers +assert machine.identityMap() +assert machine.regIRM(1)==[1] +assert machine.regIRM(2)==[2] +assert machine.regIRM(3)==[3] +assert machine.regIRM(4)==[(4,1),1] +assert machine.regIRM(5)==[(5,2),2] +assert machine.regIRM(2)==[(5,3),3] +assert machine.regIRM(3)==[2] + + +#assert machine.regIRM(2)==[(4,3),3] +#assert machine.map()=={1:1,2:3,3:4,4:2,5:5} + + + + + + + + + Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 18:21:43 2005 @@ -4,10 +4,104 @@ from pypy.translator.asm.infregmachine import Instruction from pypy.objspace.flow.model import Constant +""" +Notes on the register allocation algorithm: + + +To convert our IRM to an FRM machine, we must perform some swapping of the registers. This is in effect +'paging', we are only allowed to perform XCHG operations on the slow (memory) registers, while we can do +anything with our fast (CPU registers). + +There are various algorithms available, including the Linear Scan Algorithm (google this), but for now we +have decided to implement a simple, but (hopefully) reasonably effective last-recently-used algortithm. + +Regardless of the swap algorithm , at each stage we must keep track of which IRM register is held in which +FRM register. Our original test-suite simply gave the register usages, and checked the swap/usage sequence. + +We need to rebuild the suite, checking the register map at EACH stage of the process. Fiddly, but important! + +We need some notation: + +IRMxxx denotes an Infinite Register Machine that will use at most xxx registers + +FRMxxx.yyy denotes a finite-register machine, with xxx fast registers, and a total of yyy registers. + +""" + + +def regmap(regperm): + import operator + """answer a map IRM notation -> current FRM notation""" + map={} + for reg in range(1,len(regperm)): + #print reg,map,regperm + map[reg]=regperm.index(reg) + return map + +def maxRegister(commands): + pool=[] + for cmd in commands: + if not isinstance(cmd,str): + pool+=cmd.registers_used() + if pool==[]: + return 1 + return max(pool) + + +def TranslateProgram(commands,nreg): + """answer this program into one which only uses nreg fast registers""" + totreg=max([max(cmd.registers_used()) for cmd in commands]) + totreg=maxRegister(commands) + assert nreg>=3 ,'Some commands may use 3 registers!!!!' + assert totreg>=nreg + newprog=[] + pipe=[] + old2new=range(0,totreg+1) #this must be as big as the total number of registers+1 (we start at index 1) + + + for cmd in commands: + #if we use any registers, we must possibly swap first, and then remap + if isinstance(cmd,str) or cmd.name in ('J','JT','JF'): #label or jump so pass through + newprog.append(cmd) + else: + #so now remap the registers! + + regused=cmd.registers_used() + t2p=[old2new[x] for x in regused] + for reg in regused: + goingin=regmap(old2new)[reg] + if goingin>nreg: + if pipe[-1] not in t2p: + index=-1 + elif pipe[-2] not in t2p: + index=-2 + else: + assert pipe[-3]!=goingin #this must be true for nreg>=3 + index=-3 + #now swap to end of pipe, so code as before works. + pipe[index],pipe[-1]=pipe[-1],pipe[index] + goingout=pipe[-1] + newprog.append(Instruction('EXCH',(goingin,goingout))) + old2new[goingout],old2new[goingin] = old2new[goingin],old2new[goingout] + val=goingout + else: + val=goingin + pipe=[val]+pipe + + if len(pipe)>nreg: + pipe.pop() #this value fell out of the pipe + assert len(pipe)<=nreg + #now we can emit the command with registers remapped + rm=regmap(old2new) + newprog.append(cmd.renumber(rm)) + return newprog + + + class Machine: - def RunProgram(cls,commands,args=[],nreg=10,tracing=False): - #run this program + def RunProgram(cls,commands,args=[],tracing=False): + nreg=maxRegister(commands) machine=Machine(nreg,args) machine._tracing = tracing ip=0 @@ -65,8 +159,8 @@ args.append('r%s=%s'%(arg, self._registers[arg])) else: args.append(arg) - print opcode, ', '.join(map(str, args)) - #will want to trap later to defer unimplemented to the LLInterpreter... + #print opcode, ', '.join(map(str, args)) + #will want to trap later to defer unimplemented to the LLInterpreter... m = getattr(self,opcode,None) if m is not None: m(*operands) @@ -87,7 +181,8 @@ self._registers[destination]=self.register(source) def EXCH(self,destination,source): - self._registers[destination],self._registers[source]=self.register(source),self.register(destination) + #self._registers[destination],self._registers[source]=self.register(source),self.register(destination) + self._registers[destination],self._registers[source]=self._registers[source],self._registers[destination] def int_gt(self,rega,regb): @@ -116,3 +211,6 @@ self._registers[destination] = LLFrame.__dict__['op_'+opcode](None, *sourcevalues) + + + Modified: pypy/dist/pypy/translator/asm/test/test_simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_simulator.py (original) +++ pypy/dist/pypy/translator/asm/test/test_simulator.py Wed Oct 12 18:21:43 2005 @@ -1,5 +1,8 @@ +import random import autopath -from pypy.translator.asm.simulator import Machine + + +from pypy.translator.asm.simulator import Machine,TranslateProgram from pypy.objspace.flow.model import Constant from pypy.translator.asm.infregmachine import Instruction @@ -63,7 +66,44 @@ Instruction('LIA', (3, Constant(2))), 'label', Instruction('RETPYTHON', (3,))] - + assert Machine.RunProgram(prog, [1,2,3]) == 3 assert Machine.RunProgram(prog, [2,1,3]) == 77 + +#now we want to test our translation system. +#we create a random program, and demonstrate that the results are the same in translated and untranslated form + + + +def test_translation(n=10,runs=20,size=50): + random.seed(1001) #ensure we get the same tests each time + def r(): + return random.randint(1,n) + + for x in range(runs): + prog=[] + for v in range(1,n+1): + prog.append(Instruction('LOAD',(v,Constant(v*10)))) + for v in range(size): + prog.append(Instruction('EXCH',(r(),r()))) + prog.append(Instruction('MOV',(r(),r()))) + prog.append(Instruction('int_add',(r(),r(),r()))) + + prog.append('foo') + for exitreg in range(1,n+1): + prog[-1]=Instruction('RETPYTHON',(exitreg,)) + assert Machine.RunProgram(prog)==Machine.RunProgram(TranslateProgram(prog,nreg=3)) + + +def test_zeroRegisterAbuse(): + try: + Machine.RunProgram([Instruction('MOV',(0,0))]) + except AssertionError: + pass + else: + assert False, "should not get here" + + + + From mwh at codespeak.net Wed Oct 12 18:25:06 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 18:25:06 +0200 (CEST) Subject: [pypy-svn] r18495 - pypy/dist/pypy/translator/asm Message-ID: <20051012162506.0276C27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 18:25:05 2005 New Revision: 18495 Modified: pypy/dist/pypy/translator/asm/genasm.py Log: that parameter has gone. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 18:25:05 2005 @@ -54,7 +54,6 @@ def r(*args): return Machine.RunProgram(g.assembler.instructions, args, - 1000, tracing=True) return r From mwh at codespeak.net Wed Oct 12 18:30:46 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 18:30:46 +0200 (CEST) Subject: [pypy-svn] r18496 - pypy/dist/pypy/translator/asm Message-ID: <20051012163046.6D16127B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 18:30:44 2005 New Revision: 18496 Modified: pypy/dist/pypy/translator/asm/simulator.py Log: this can go! Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 18:30:44 2005 @@ -50,7 +50,6 @@ def TranslateProgram(commands,nreg): """answer this program into one which only uses nreg fast registers""" - totreg=max([max(cmd.registers_used()) for cmd in commands]) totreg=maxRegister(commands) assert nreg>=3 ,'Some commands may use 3 registers!!!!' assert totreg>=nreg From mwh at codespeak.net Wed Oct 12 18:32:21 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 18:32:21 +0200 (CEST) Subject: [pypy-svn] r18497 - pypy/dist/pypy/translator/asm Message-ID: <20051012163221.0F05027B50@code1.codespeak.net> Author: mwh Date: Wed Oct 12 18:32:18 2005 New Revision: 18497 Modified: pypy/dist/pypy/translator/asm/simulator.py Log: this line too! Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 18:32:18 2005 @@ -52,7 +52,6 @@ """answer this program into one which only uses nreg fast registers""" totreg=maxRegister(commands) assert nreg>=3 ,'Some commands may use 3 registers!!!!' - assert totreg>=nreg newprog=[] pipe=[] old2new=range(0,totreg+1) #this must be as big as the total number of registers+1 (we start at index 1) From ac at codespeak.net Wed Oct 12 18:34:39 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Wed, 12 Oct 2005 18:34:39 +0200 (CEST) Subject: [pypy-svn] r18498 - in pypy/branch/hl-backend/pypy: annotation annotation/test rpython/ootype rpython/ootype/test Message-ID: <20051012163439.F0A8427B50@code1.codespeak.net> Author: ac Date: Wed Oct 12 18:34:39 2005 New Revision: 18498 Modified: pypy/branch/hl-backend/pypy/annotation/binaryop.py pypy/branch/hl-backend/pypy/annotation/bookkeeper.py pypy/branch/hl-backend/pypy/annotation/builtin.py pypy/branch/hl-backend/pypy/annotation/model.py pypy/branch/hl-backend/pypy/annotation/test/test_model.py pypy/branch/hl-backend/pypy/annotation/unaryop.py pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Log: Restructure the typemodel of ootype. Modified: pypy/branch/hl-backend/pypy/annotation/binaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/binaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/binaryop.py Wed Oct 12 18:34:39 2005 @@ -652,7 +652,8 @@ # ____________________________________________________________ # annotation of low-level types -from pypy.annotation.model import SomePtr, SomeRef, ll_to_annotation, annotation_to_lltype +from pypy.annotation.model import SomePtr, SomeOOInstance, SomeOOClass +from pypy.annotation.model import ll_to_annotation, annotation_to_lltype from pypy.rpython.ootype import ootype class __extend__(pairtype(SomePtr, SomePtr)): @@ -688,17 +689,23 @@ return pair(p2, obj).union() -class __extend__(pairtype(SomeRef, SomeRef)): +class __extend__(pairtype(SomeOOInstance, SomeOOInstance)): + def union((r1, r2)): + common = ootype.commonBaseclass(r1.ootype, r2.ootype) + assert common is not None, 'Mixing of incompatible instances %r, %r' %(r1.ootype, r2.ootype) + return SomeOOInstance(common) + +class __extend__(pairtype(SomeOOClass, SomeOOClass)): def union((r1, r2)): common = ootype.commonBaseclass(r1.ootype, r2.ootype) assert common is not None, 'Mixing of incompatible classes %r, %r' %(r1.ootype, r2.ootype) - return SomeRef(common) + return SomeOOClass(common) -class __extend__(pairtype(SomeRef, SomeObject)): +class __extend__(pairtype(SomeOOInstance, SomeObject)): def union((r, obj)): assert False, ("mixing reference type %r with something else %r" % (r.ootype, obj)) -class __extend__(pairtype(SomeObject, SomeRef)): +class __extend__(pairtype(SomeObject, SomeOOInstance)): def union((obj, r2)): return pair(r2, obj).union() Modified: pypy/branch/hl-backend/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/bookkeeper.py (original) +++ pypy/branch/hl-backend/pypy/annotation/bookkeeper.py Wed Oct 12 18:34:39 2005 @@ -354,7 +354,7 @@ assert x is lladdress.NULL result= SomeAddress(is_null=True) elif isinstance(x, ootype._static_meth): - result = SomeStaticMeth(ootype.typeOf(x)) + result = SomeOOStaticMeth(ootype.typeOf(x)) elif callable(x) or isinstance(x, staticmethod): # XXX # maybe 'x' is a method bound to a not-yet-frozen cache? # fun fun fun. Modified: pypy/branch/hl-backend/pypy/annotation/builtin.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/builtin.py (original) +++ pypy/branch/hl-backend/pypy/annotation/builtin.py Wed Oct 12 18:34:39 2005 @@ -365,29 +365,39 @@ BUILTIN_ANALYZERS[lltype.runtime_type_info] = runtime_type_info # ootype -from pypy.annotation.model import SomeRef +from pypy.annotation.model import SomeOOInstance, SomeOOClass from pypy.rpython.ootype import ootype -def new(C): - assert C.is_constant() - i = ootype.new(C.const) - r = SomeRef(ootype.typeOf(i)) +def new(I): + assert I.is_constant() + i = ootype.new(I.const) + r = SomeOOInstance(ootype.typeOf(i)) return r -def null(C): - assert C.is_constant() - i = ootype.null(C.const) - r = SomeRef(ootype.typeOf(i)) +def null(I): + assert I.is_constant() + i = ootype.null(I.const) + r = SomeOOInstance(ootype.typeOf(i)) return r -def instanceof(c, C): - assert C.is_constant() - assert isinstance(C.const, ootype.Class) +def instanceof(i, I): + assert I.is_constant() + assert isinstance(I.const, ootype.Instance) return SomeBool() +def classof(i): + assert isinstance(i, SomeOOInstance) + return SomeOOClass(i.ootype) + +def runtimenew(c): + assert isinstance(c, SomeOOClass) + return SomeOOInstance(c.ootype) + BUILTIN_ANALYZERS[ootype.instanceof] = instanceof BUILTIN_ANALYZERS[ootype.new] = new BUILTIN_ANALYZERS[ootype.null] = null +BUILTIN_ANALYZERS[ootype.runtimenew] = runtimenew +BUILTIN_ANALYZERS[ootype.classof] = classof #________________________________ # non-gc objects Modified: pypy/branch/hl-backend/pypy/annotation/model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/model.py Wed Oct 12 18:34:39 2005 @@ -431,16 +431,20 @@ def can_be_none(self): return False -class SomeRef(SomeObject): +class SomeOOClass(SomeObject): def __init__(self, ootype): self.ootype = ootype -class SomeBoundMeth(SomeObject): +class SomeOOInstance(SomeObject): + def __init__(self, ootype): + self.ootype = ootype + +class SomeOOBoundMeth(SomeObject): def __init__(self, ootype, name): self.ootype = ootype self.name = name -class SomeStaticMeth(SomeObject): +class SomeOOStaticMeth(SomeObject): def __init__(self, method): self.method = method @@ -459,7 +463,7 @@ ] def annotation_to_lltype(s_val, info=None): - if isinstance(s_val, SomeRef): + if isinstance(s_val, SomeOOInstance): return s_val.ootype if isinstance(s_val, SomePtr): return s_val.ll_ptrtype @@ -478,8 +482,8 @@ def lltype_to_annotation(T): s = ll_to_annotation_map.get(T) if s is None: - if isinstance(T, ootype.Class): - return SomeRef(T) + if isinstance(T, ootype.Instance): + return SomeOOInstance(T) else: return SomePtr(T) else: Modified: pypy/branch/hl-backend/pypy/annotation/test/test_model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/test/test_model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/test/test_model.py Wed Oct 12 18:34:39 2005 @@ -118,9 +118,9 @@ assert isinstance(s_p, SomePtr) and s_p.ll_ptrtype == lltype.Ptr(S) s_p = ll_to_annotation(lltype.malloc(A, 0)) assert isinstance(s_p, SomePtr) and s_p.ll_ptrtype == lltype.Ptr(A) - C = ootype.Class('C', None, {}) + C = ootype.Instance('C', None, {}) s_p = ll_to_annotation(ootype.new(C)) - assert isinstance(s_p, SomeRef) and s_p.ootype == C + assert isinstance(s_p, SomeOOInstance) and s_p.ootype == C def test_annotation_to_lltype(): from pypy.rpython.rarithmetic import r_uint @@ -143,8 +143,8 @@ s_p = SomePtr(ll_ptrtype=PS) assert annotation_to_lltype(s_p) == PS py.test.raises(ValueError, "annotation_to_lltype(si0)") - C = ootype.Class('C', None, {}) - ref = SomeRef(C) + C = ootype.Instance('C', None, {}) + ref = SomeOOInstance(C) assert annotation_to_lltype(ref) == C def test_ll_union(): @@ -173,24 +173,24 @@ py.test.raises(AssertionError, "unionof(SomeObject(), SomePtr(PS1))") def test_oo_union(): - C1 = ootype.Class("C1", None) - C2 = ootype.Class("C2", C1) - C3 = ootype.Class("C3", C1) - D = ootype.Class("D", None) - assert unionof(SomeRef(C1), SomeRef(C1)) == SomeRef(C1) - assert unionof(SomeRef(C1), SomeRef(C2)) == SomeRef(C1) - assert unionof(SomeRef(C2), SomeRef(C1)) == SomeRef(C1) - assert unionof(SomeRef(C2), SomeRef(C3)) == SomeRef(C1) - - assert unionof(SomeRef(C1),SomeImpossibleValue()) == SomeRef(C1) - assert unionof(SomeImpossibleValue(), SomeRef(C1)) == SomeRef(C1) - - py.test.raises(AssertionError, "unionof(SomeRef(C1), SomeRef(D))") - py.test.raises(AssertionError, "unionof(SomeRef(D), SomeRef(C1))") - py.test.raises(AssertionError, "unionof(SomeRef(C1), SomeInteger())") - py.test.raises(AssertionError, "unionof(SomeInteger(), SomeRef(C1))") - py.test.raises(AssertionError, "unionof(SomeRef(C1), SomeObject())") - py.test.raises(AssertionError, "unionof(SomeObject(), SomeRef(C1))") + C1 = ootype.Instance("C1", None) + C2 = ootype.Instance("C2", C1) + C3 = ootype.Instance("C3", C1) + D = ootype.Instance("D", None) + assert unionof(SomeOOInstance(C1), SomeOOInstance(C1)) == SomeOOInstance(C1) + assert unionof(SomeOOInstance(C1), SomeOOInstance(C2)) == SomeOOInstance(C1) + assert unionof(SomeOOInstance(C2), SomeOOInstance(C1)) == SomeOOInstance(C1) + assert unionof(SomeOOInstance(C2), SomeOOInstance(C3)) == SomeOOInstance(C1) + + assert unionof(SomeOOInstance(C1),SomeImpossibleValue()) == SomeOOInstance(C1) + assert unionof(SomeImpossibleValue(), SomeOOInstance(C1)) == SomeOOInstance(C1) + + py.test.raises(AssertionError, "unionof(SomeOOInstance(C1), SomeOOInstance(D))") + py.test.raises(AssertionError, "unionof(SomeOOInstance(D), SomeOOInstance(C1))") + py.test.raises(AssertionError, "unionof(SomeOOInstance(C1), SomeInteger())") + py.test.raises(AssertionError, "unionof(SomeInteger(), SomeOOInstance(C1))") + py.test.raises(AssertionError, "unionof(SomeOOInstance(C1), SomeObject())") + py.test.raises(AssertionError, "unionof(SomeObject(), SomeOOInstance(C1))") if __name__ == '__main__': for name, value in globals().items(): Modified: pypy/branch/hl-backend/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/unaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/unaryop.py Wed Oct 12 18:34:39 2005 @@ -566,7 +566,7 @@ # annotation of low-level types -from pypy.annotation.model import SomePtr, SomeRef, SomeBoundMeth, SomeStaticMeth +from pypy.annotation.model import SomePtr, SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth from pypy.annotation.model import ll_to_annotation, annotation_to_lltype class __extend__(SomePtr): @@ -595,22 +595,22 @@ return SomeBool() from pypy.rpython.ootype import ootype -class __extend__(SomeRef): +class __extend__(SomeOOInstance): def getattr(r, s_attr): assert s_attr.is_constant(), "getattr on ref %r with non-constant field-name" % r.ootype v = getattr(r.ootype._example(), s_attr.const) if isinstance(v, ootype._bound_meth): - return SomeBoundMeth(r.ootype, s_attr.const) + return SomeOOBoundMeth(r.ootype, s_attr.const) return ll_to_annotation(v) -class __extend__(SomeBoundMeth): +class __extend__(SomeOOBoundMeth): def simple_call(m, *args_s): llargs = [annotation_to_lltype(arg_s)._example() for arg_s in args_s] inst = m.ootype._example() v = getattr(inst, m.name)(*llargs) return ll_to_annotation(v) -class __extend__(SomeStaticMeth): +class __extend__(SomeOOStaticMeth): def simple_call(m, *args_s): llargs = [annotation_to_lltype(arg_s)._example() for arg_s in args_s] smeth = m.method._example() Modified: pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/ootype.py Wed Oct 12 18:34:39 2005 @@ -12,7 +12,11 @@ pass class Class(OOType): + pass +Class = Class() +class Instance(OOType): + """this is the type of user-defined objects""" def __init__(self, name, superclass, fields={}, methods={}): self._name = name self._superclass = superclass @@ -24,7 +28,8 @@ self._add_methods(methods) self._null = _null_instance(self) - + self._class = _class(self) + def _defl(self): return self._null @@ -110,13 +115,17 @@ StaticMethod.__init__(self, args, result) # ____________________________________________________________ +class _class(object): + _TYPE = Class + def __init__(self, INSTANCE): + self._INSTANCE = INSTANCE + class _instance(object): - def __init__(self, CLASS): - self.__dict__["_TYPE"] = CLASS - - CLASS._init_instance(self) - + def __init__(self, INSTANCE): + self.__dict__["_TYPE"] = INSTANCE + INSTANCE._init_instance(self) + def __getattr__(self, name): meth = self._TYPE._lookup(name) if meth is not None: @@ -136,8 +145,8 @@ class _null_instance(_instance): - def __init__(self, CLASS): - self.__dict__["_TYPE"] = CLASS + def __init__(self, INSTANCE): + self.__dict__["_TYPE"] = INSTANCE def __getattribute__(self, name): if name.startswith("_"): @@ -166,7 +175,7 @@ for a, ARG in zip(args, self._TYPE.ARGS): if typeOf(a) != ARG: - if isinstance(ARG, Class) and isinstance(a, _instance): + if isinstance(ARG, Instance) and isinstance(a, _instance): if instanceof(a, ARG): continue raise TypeError,"calling %r with wrong argument types: %r" % (self._TYPE, args) @@ -205,8 +214,12 @@ def __call__(self, *args): return self.meth._checkargs(args)(self.inst, *args) -def new(CLASS): - return _instance(CLASS) +def new(INSTANCE): + return _instance(INSTANCE) + +def runtimenew(class_): + assert isinstance(class_, _class) + return _instance(class_._INSTANCE) def static_meth(FUNCTION, name, **attrs): return _static_meth(FUNCTION, _name=name, **attrs) @@ -214,17 +227,24 @@ def meth(METHOD, **attrs): return _meth(METHOD, **attrs) -def null(CLASS): - return CLASS._null +def null(INSTANCE): + return INSTANCE._null + +def instanceof(inst, INSTANCE): + return isSubclass(inst._TYPE, INSTANCE) + +def classof(inst): + return runtimeClass(inst._TYPE) -def addFields(CLASS, fields): - CLASS._add_fields(fields) +def addFields(INSTANCE, fields): + INSTANCE._add_fields(fields) -def addMethods(CLASS, methods): - CLASS._add_methods(methods) +def addMethods(INSTANCE, methods): + INSTANCE._add_methods(methods) -def instanceof(inst, CLASS): - return isSubclass(inst._TYPE, CLASS) +def runtimeClass(INSTANCE): + assert isinstance(INSTANCE, Instance) + return INSTANCE._class def isSubclass(C1, C2): c = C1 @@ -234,10 +254,10 @@ c = c._superclass return False -def commonBaseclass(CLASS1, CLASS2): - c = CLASS1 +def commonBaseclass(INSTANCE1, INSTANCE2): + c = INSTANCE1 while c is not None: - if isSubclass(CLASS2, c): + if isSubclass(INSTANCE2, c): return c c = c._superclass return None Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py Wed Oct 12 18:34:39 2005 @@ -5,7 +5,7 @@ def test_simple_new(): - C = Class("test", None, {'a': Signed}) + C = Instance("test", None, {'a': Signed}) def oof(): c = new(C) @@ -18,7 +18,7 @@ assert s.knowntype == int def test_simple_instanceof(): - C = Class("test", None, {'a': Signed}) + C = Instance("test", None, {'a': Signed}) def oof(): c = new(C) @@ -31,20 +31,69 @@ assert s.knowntype == bool def test_simple_null(): - C = Class("test", None, {'a': Signed}) + I = Instance("test", None, {'a': Signed}) def oof(): - c = null(C) - return c + i = null(I) + return i + + a = RPythonAnnotator() + s = a.build_types(oof, []) + #a.translator.view() + + assert s == annmodel.SomeOOInstance(I) + +def test_simple_classof(): + I = Instance("test", None, {'a': Signed}) + + def oof(): + i = new(I) + return classof(i) + + a = RPythonAnnotator() + s = a.build_types(oof, []) + #a.translator.view() + + assert s == annmodel.SomeOOClass(I) + +def test_simple_runtimenew(): + I = Instance("test", None, {'a': Signed}) + + def oof(): + i = new(I) + c = classof(i) + i2 = runtimenew(c) + return i2 a = RPythonAnnotator() s = a.build_types(oof, []) #a.translator.view() - assert s == annmodel.SomeRef(C) + assert s == annmodel.SomeOOInstance(I) + +def test_complex_runtimenew(): + I = Instance("test", None, {'a': Signed}) + J = Instance("test2", I, {'b': Signed}) + K = Instance("test2", I, {'b': Signed}) + + def oof(x): + k = new(K) + j = new(J) + if x: + c = classof(k) + else: + c = classof(j) + i = runtimenew(c) + return i + + a = RPythonAnnotator() + s = a.build_types(oof, [bool]) + #a.translator.view() + + assert s == annmodel.SomeOOInstance(I) def test_method(): - C = Class("test", None, {"a": (Signed, 3)}) + C = Instance("test", None, {"a": (Signed, 3)}) M = Meth([C], Signed) def m_(self, other): @@ -64,9 +113,9 @@ assert s.knowntype == int def test_unionof(): - C1 = Class("C1", None) - C2 = Class("C2", C1) - C3 = Class("C3", C1) + C1 = Instance("C1", None) + C2 = Instance("C2", C1) + C3 = Instance("C3", C1) def oof(f): if f: @@ -79,7 +128,7 @@ s = a.build_types(oof, [bool]) #a.translator.view() - assert s == annmodel.SomeRef(C1) + assert s == annmodel.SomeOOInstance(C1) def test_static_method(): F = StaticMethod([Signed, Signed], Signed) @@ -94,5 +143,5 @@ s = a.build_types(oof, []) #a.translator.view() - assert s.knowntype = int + assert s.knowntype == int Modified: pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py Wed Oct 12 18:34:39 2005 @@ -9,31 +9,52 @@ def m_(self, b): return self.a + b m = meth(M, _name="m", _callable=m_) - C = Class("test", None, {"a": Signed}, {"m": m}) - assert type(hash(C)) == int + I = Instance("test", None, {"a": Signed}, {"m": m}) + assert type(hash(I)) == int def test_simple_class(): - C = Class("test", None, {"a": Signed}) + I = Instance("test", None, {"a": Signed}) + i = new(I) - c = new(C) - assert typeOf(c) == C - - py.test.raises(TypeError, "c.z") - py.test.raises(TypeError, "c.a = 3.0") + py.test.raises(TypeError, "i.z") + py.test.raises(TypeError, "i.a = 3.0") + + i.a = 3 + assert i.a == 3 + +def test_runtime_instanciation(): + I = Instance("test", None, {"a": Signed}) + c = runtimeClass(I) + i = runtimenew(c) - c.a = 3 - assert c.a == 3 + assert typeOf(i) == I + assert typeOf(c) == Class +def test_classof(): + I = Instance("test", None, {"a": Signed}) + c = runtimeClass(I) + i = new(I) + + assert classof(i) == c + + j = new(I) + + assert classof(i) is classof(j) + I2 = Instance("test2", I, {"b": Signed}) + i2 = new(I2) + assert classof(i2) is not classof(i) + assert classof(i2) != classof(i) + def test_simple_default_class(): - C = Class("test", None, {"a": (Signed, 3)}) + I = Instance("test", None, {"a": (Signed, 3)}) + i = new(I) - c = new(C) - assert c.a == 3 + assert i.a == 3 - py.test.raises(TypeError, "Class('test', None, {'a': (Signed, 3.0)})") + py.test.raises(TypeError, "Instance('test', None, {'a': (Signed, 3.0)})") def test_simple_null(): - C = Class("test", None, {"a": Signed}) + C = Instance("test", None, {"a": Signed}) c = null(C) assert typeOf(c) == C @@ -41,9 +62,9 @@ py.test.raises(RuntimeError, "c.a") def test_simple_class_field(): - C = Class("test", None, {}) + C = Instance("test", None, {}) - D = Class("test2", None, {"a": C}) + D = Instance("test2", None, {"a": C}) d = new(D) assert typeOf(d.a) == C @@ -51,7 +72,7 @@ assert d.a == null(C) def test_simple_recursive_class(): - C = Class("test", None, {}) + C = Instance("test", None, {}) addFields(C, {"inst": C}) @@ -59,16 +80,16 @@ assert c.inst == null(C) def test_simple_super(): - C = Class("test", None, {"a": (Signed, 3)}) - D = Class("test2", C, {}) + C = Instance("test", None, {"a": (Signed, 3)}) + D = Instance("test2", C, {}) d = new(D) assert d.a == 3 def test_simple_field_shadowing(): - C = Class("test", None, {"a": (Signed, 3)}) + C = Instance("test", None, {"a": (Signed, 3)}) - py.test.raises(TypeError, """D = Class("test2", C, {"a": (Signed, 3)})""") + py.test.raises(TypeError, """D = Instance("test2", C, {"a": (Signed, 3)})""") def test_simple_static_method(): F = StaticMethod([Signed, Signed], Signed) @@ -97,7 +118,7 @@ return self.a + b m = meth(M, _name="m", _callable=m_) - C = Class("test", None, {"a": (Signed, 2)}, {"m": m}) + C = Instance("test", None, {"a": (Signed, 2)}, {"m": m}) c = new(C) assert c.m(3) == 5 @@ -112,12 +133,12 @@ return self.a + b m = meth(M, _name="m", _callable=m_) - py.test.raises(TypeError, """Class("test", None, {"a": M})""") + py.test.raises(TypeError, """Instance("test", None, {"a": M})""") - py.test.raises(TypeError, """Class("test", None, {"m": Signed}, {"m":m})""") + py.test.raises(TypeError, """Instance("test", None, {"m": Signed}, {"m":m})""") def test_simple_recursive_meth(): - C = Class("test", None, {"a": (Signed, 3)}) + C = Instance("test", None, {"a": (Signed, 3)}) M = Meth([C], Signed) def m_(self, other): @@ -130,7 +151,7 @@ assert c.m(c) == 6 def test_explicit_name_clash(): - C = Class("test", None, {}) + C = Instance("test", None, {}) addFields(C, {"a": (Signed, 3)}) @@ -144,8 +165,8 @@ py.test.raises(TypeError, """addFields(C, {"b": Signed})""") def test_instanceof(): - C = Class("test", None, {}) - D = Class("test2", C, {}) + C = Instance("test", None, {}) + D = Instance("test2", C, {}) c = new(C) d = new(D) assert instanceof(c, C) @@ -154,7 +175,7 @@ assert instanceof(d, C) def test_superclass_meth_lookup(): - C = Class("test", None, {"a": (Signed, 3)}) + C = Instance("test", None, {"a": (Signed, 3)}) M = Meth([C], Signed) def m_(self, other): @@ -163,7 +184,7 @@ addMethods(C, {"m": m}) - D = Class("test2", C, {}) + D = Instance("test2", C, {}) d = new(D) assert d.m(d) == 6 @@ -177,10 +198,10 @@ assert d.m(d) == 9 def test_isSubclass(): - A = Class("A", None) - B = Class("B", A) - C = Class("C", A) - D = Class("D", C) + A = Instance("A", None) + B = Instance("B", A) + C = Instance("C", A) + D = Instance("D", C) assert isSubclass(A, A) assert isSubclass(B, A) @@ -192,12 +213,12 @@ assert not isSubclass(D, B) def test_commonBaseclass(): - A = Class("A", None) - B = Class("B", A) - C = Class("C", A) - D = Class("D", C) - E = Class("E", None) - F = Class("F", E) + A = Instance("A", None) + B = Instance("B", A) + C = Instance("C", A) + D = Instance("D", C) + E = Instance("E", None) + F = Instance("F", E) assert commonBaseclass(A, A) == A assert commonBaseclass(A, B) == A From afa at codespeak.net Wed Oct 12 18:39:45 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 18:39:45 +0200 (CEST) Subject: [pypy-svn] r18499 - pypy/dist/pypy/rpython Message-ID: <20051012163945.3AC8927B4E@code1.codespeak.net> Author: afa Date: Wed Oct 12 18:39:43 2005 New Revision: 18499 Modified: pypy/dist/pypy/rpython/rtyper.py Log: (valentino, afa, arigo): correct insertion of stack checks Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Wed Oct 12 18:39:43 2005 @@ -109,8 +109,8 @@ """Main entry point: specialize all annotated blocks of the program.""" self.crash_on_first_typeerror = crash_on_first_typeerror # specialize depends on annotator simplifications + insert_stackcheck(self.annotator) if not dont_simplify_again: - insert_stackcheck(self.annotator) self.annotator.simplify() # first make sure that all functions called in a group have exactly From mwh at codespeak.net Wed Oct 12 18:49:10 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 18:49:10 +0200 (CEST) Subject: [pypy-svn] r18500 - in pypy/dist/pypy/translator/asm: . ppc test Message-ID: <20051012164910.56D8B27B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 18:49:07 2005 New Revision: 18500 Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/ppc/codegen.py pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: test functions on the simulator after register allocation too. Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 12 18:49:07 2005 @@ -2,7 +2,7 @@ from pypy.objspace.flow.model import traverse, Block, Variable, Constant from pypy.translator.asm import infregmachine from pypy.rpython.lltype import Signed -from pypy.translator.asm.simulator import Machine +from pypy.translator.asm.simulator import Machine, TranslateProgram #Available Machine code targets (processor+operating system) TARGET_UNKNOWN=0 @@ -57,6 +57,16 @@ tracing=True) return r + elif processor == 'virtfinite': + insns = TranslateProgram(g.assembler.instructions, 50) + for i in insns: + print i + def r(*args): + return Machine.RunProgram(insns, + args, + tracing=True) + + return r elif processor == 'ppc': from pypy.translator.asm.ppc import codegen return codegen.make_native_code(graph, g.assembler.instructions) Modified: pypy/dist/pypy/translator/asm/ppc/codegen.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppc/codegen.py (original) +++ pypy/dist/pypy/translator/asm/ppc/codegen.py Wed Oct 12 18:49:07 2005 @@ -1,4 +1,5 @@ + def make_native_code(graph, infreginsns): from pypy.translator.asm.ppcgen.func_builder import make_func maxregs = 0 @@ -8,10 +9,12 @@ for r in insn.registers_used(): maxregs = max(r, maxregs) - from pypy.translator.asm import regalloc + from pypy.translator.asm import regalloc, simulator insns = regalloc.regalloc(infreginsns, 30) + #insns = simulator.TranslateProgram(infreginsns, 5) + codegen = PPCCodeGen() return make_func(codegen.assemble(insns), 'i', Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 12 18:49:07 2005 @@ -157,7 +157,7 @@ args.append('r%s=%s'%(arg, self._registers[arg])) else: args.append(arg) - #print opcode, ', '.join(map(str, args)) + print opcode, ', '.join(map(str, args)) #will want to trap later to defer unimplemented to the LLInterpreter... m = getattr(self,opcode,None) if m is not None: Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Wed Oct 12 18:49:07 2005 @@ -121,6 +121,11 @@ big = 1000000000 assert f(big, big) == g(big, big) +class TestAsmAfterAllocation(TestAsm): + + processor = 'virtfinite' + + class TestAsmPPC(TestAsm): processor = 'ppc' From arigo at codespeak.net Wed Oct 12 18:53:48 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 12 Oct 2005 18:53:48 +0200 (CEST) Subject: [pypy-svn] r18501 - pypy/dist/pypy/translator/goal Message-ID: <20051012165348.22AAE27B4E@code1.codespeak.net> Author: arigo Date: Wed Oct 12 18:53:47 2005 New Revision: 18501 Modified: pypy/dist/pypy/translator/goal/targetnopstandalone.py Log: Made targetnopstandalone trivial again -- printing hello world. Please make a copy of it for testing; this one is nice to have as a starting point for other experiments. Modified: pypy/dist/pypy/translator/goal/targetnopstandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetnopstandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetnopstandalone.py Wed Oct 12 18:53:47 2005 @@ -1,5 +1,4 @@ import os, sys -from pypy.translator.test.snippet import sieve_of_eratosthenes as soe def debug(msg): os.write(2, "debug: " + msg + '\n') @@ -8,8 +7,8 @@ # __________ Entry point __________ def entry_point(argv): - count = soe() - return count + debug("hello world") + return 0 # _____ Define and setup target ___ From mwh at codespeak.net Wed Oct 12 18:57:56 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 12 Oct 2005 18:57:56 +0200 (CEST) Subject: [pypy-svn] r18502 - pypy/dist/pypy/translator Message-ID: <20051012165756.C7B0827B4E@code1.codespeak.net> Author: mwh Date: Wed Oct 12 18:57:55 2005 New Revision: 18502 Modified: pypy/dist/pypy/translator/translator.py Log: ARGH! Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Wed Oct 12 18:57:55 2005 @@ -329,7 +329,7 @@ def asmcompile(self, processor='virt'): from pypy.translator.asm import genasm - assert processor in ['ppc', 'virt'] + assert processor in ['ppc', 'virt', 'virtfinite'] assert self.rtyper is not None, 'must specialize' return genasm.genasm(self, processor) From afa at codespeak.net Wed Oct 12 19:01:26 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 12 Oct 2005 19:01:26 +0200 (CEST) Subject: [pypy-svn] r18503 - pypy/dist/pypy/translator/goal Message-ID: <20051012170126.6D5E127B4E@code1.codespeak.net> Author: afa Date: Wed Oct 12 19:01:25 2005 New Revision: 18503 Modified: pypy/dist/pypy/translator/goal/targetnopstandalone.py Log: Adding a comment telling how to build a standalone target Modified: pypy/dist/pypy/translator/goal/targetnopstandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetnopstandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetnopstandalone.py Wed Oct 12 19:01:25 2005 @@ -1,8 +1,16 @@ +""" +A simple standalone target. + +The target below specifies None as the argument types list. +This is a case treated specially in driver.py . If the list +of input types is empty, it is meant to be a list of strings, +actually implementing argv of the executable. +""" + import os, sys def debug(msg): os.write(2, "debug: " + msg + '\n') - # __________ Entry point __________ @@ -14,4 +22,3 @@ def target(*args): return entry_point, None - From arigo at codespeak.net Wed Oct 12 19:23:47 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 12 Oct 2005 19:23:47 +0200 (CEST) Subject: [pypy-svn] r18505 - pypy/dist/pypy/translator/c/test Message-ID: <20051012172347.5316627B4E@code1.codespeak.net> Author: arigo Date: Wed Oct 12 19:23:46 2005 New Revision: 18505 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: the test should work like this. 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 Oct 12 19:23:46 2005 @@ -18,20 +18,23 @@ # note: clock synchronizes itself! def test_time_clock(): - py.test.skip("time.clock like it is used here is not reliable") 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 + t3 = f1() + t4 = time.clock() + t5 = f1() + t6 = time.clock() + # time.clock() and t1() might have a different notion of zero, so + # we can only subtract two numbers returned by the same function. + assert 0 <= t2-t0 + assert 0 <= t3-t1 <= t4-t0 + assert 0 <= t4-t2 <= t5-t1 <= t6-t0 + assert 0 <= t5-t3 <= t6-t2 + assert 0 <= t6-t4 def test_time_sleep(): def does_nothing(): From tismer at codespeak.net Wed Oct 12 19:33:42 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 19:33:42 +0200 (CEST) Subject: [pypy-svn] r18507 - pypy/extradoc/sprintinfo/paris Message-ID: <20051012173342.E763B27B4E@code1.codespeak.net> Author: tismer Date: Wed Oct 12 19:33:41 2005 New Revision: 18507 Modified: pypy/extradoc/sprintinfo/paris/stackless-workplan.txt Log: status of the group Modified: pypy/extradoc/sprintinfo/paris/stackless-workplan.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/stackless-workplan.txt (original) +++ pypy/extradoc/sprintinfo/paris/stackless-workplan.txt Wed Oct 12 19:33:41 2005 @@ -5,19 +5,23 @@ People: ------- + Christian, Armin + Valentino, Amaury + Adrien, Anders + improving / refactoring ----------------------- -- (Valentino, Amaury, Armin) move stack check out of stackless.h, let it +- DONE (Valentino, Amaury, Armin) move stack check out of stackless.h, let it either unwind or raise RuntimeError -- (Valentino, Amaury, Armin) always use automatic stack check detection +- DONE (Valentino, Amaury, Armin) always use automatic stack check detection by default, and test: - - test_annotated.test_recursion_detection() - - pypy-c running CPython?s test_builtins.py + - DONE test_annotated.test_recursion_detection() + - (progressing) pypy-c running CPython?s test_builtins.py - DONE (Valentino, Amaury) make Stacklessness a translate_pypy option @@ -25,24 +29,31 @@ a stand-alone target (which is not obvious) - done by adding some comment into targetrpystonedalone.py. - Where else should we put this information? + Where else should we put this information? + targetnopstandalone.py too. performance evaluation ---------------------- -- merge stackless support and exception handling +- (thinking) merge stackless support and exception handling to produce just one if clause. Use small test programs to measure the effect (see below). -- (Anders, Chris) write smaller stand-alone applications +- DONE (Anders, Chris) write smaller stand-alone applications (rpystone, richards), provide benchmark -- check the effect of false branch predicition +- DONE (Adrien) check the effect of false branch predicition (if slp_frame_stack_bottom etc.) + + - the result appears to be identical, regardless how we + spell the conditionals :-( + +:: + if(!RPyExceptionOccured()) {} else FAIL(); -- instrument generated code to provide statistics +- (progressing) instrument generated code to provide statistics - - do some source ordering by frequency. See thoughts about + - (waiting) do some source ordering by frequency. See thoughts about this in the chapter to come, below. From tismer at codespeak.net Wed Oct 12 19:43:46 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 12 Oct 2005 19:43:46 +0200 (CEST) Subject: [pypy-svn] r18508 - in pypy/extradoc/sprintinfo: . paris Message-ID: <20051012174346.DFF8527B50@code1.codespeak.net> Author: tismer Date: Wed Oct 12 19:43:45 2005 New Revision: 18508 Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt pypy/extradoc/sprintinfo/paris/tllinterpreter_planning.txt (contents, props changed) Log: made ReST work again; eolstyle Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-planning.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-planning.txt Wed Oct 12 19:43:45 2005 @@ -18,6 +18,7 @@ ======================= stackless/cps: (same group continues, "re-"pairing inside) + christian, armin Valentino, Amaury Adrien, Anders @@ -28,8 +29,8 @@ bert, samuele, boris, arre, aurelien: different specialization to more HL-backends (defined the "ootypes" model, like the "lltypes" but more OO-ish; will start - to work on the ootyper, as a branch of the rtyper for now; same group continues - and has split in two subgroups soon -- annotator and ootyper.) +to work on the ootyper, as a branch of the rtyper for now; same group continues +and has split in two subgroups soon -- annotator and ootyper.) llinterpreter: Carl, (Armin later) (starting on the data model of the ll flow graphs, continues) @@ -42,10 +43,11 @@ discussing compiler & phase 2 work/tasks for the sprint WP09/WP10 on friday: + * short presentation from logilab/dfki about logic programming/AOP * (maybe) presentation about GC work during Summer of Code -peoples present +people present --------------------- armin Modified: pypy/extradoc/sprintinfo/paris/tllinterpreter_planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/tllinterpreter_planning.txt (original) +++ pypy/extradoc/sprintinfo/paris/tllinterpreter_planning.txt Wed Oct 12 19:43:45 2005 @@ -37,11 +37,15 @@ * what to do about types? the layout has to be compatible with what the C compilers do + - one possiblity would be to encode the types in the serialized graphs in a platform dependent manner + * how would external function calls work? + - you would probably have to have wrapper function for every signature that occurs + * it will probably be necessary to mix hl and ll. is that possible? Tasks From cfbolz at codespeak.net Wed Oct 12 19:57:21 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Wed, 12 Oct 2005 19:57:21 +0200 (CEST) Subject: [pypy-svn] r18509 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20051012175721.3387F27B50@code1.codespeak.net> Author: cfbolz Date: Wed Oct 12 19:57:16 2005 New Revision: 18509 Modified: pypy/dist/pypy/rpython/memory/gc.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/simulator.py pypy/dist/pypy/rpython/memory/test/test_gc.py pypy/dist/pypy/rpython/memory/test/test_lltypesimulation.py Log: (mwh, cfbolz): * allowed for mallocing zero bytes, which is turned into a malloc of one byte * added support for empty structs in lltypesimulation * added DummyGC, that never collects Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Wed Oct 12 19:57:16 2005 @@ -34,12 +34,14 @@ ll = AddressLinkedList() ll.append(NULL) ll.append(raw_malloc(10)) + ll.pop() #make the annotator see pop return ll def dummy_get_roots2(): ll = AddressLinkedList() ll.append(raw_malloc(10)) ll.append(NULL) + ll.pop() #make the annotator see pop return ll @@ -67,6 +69,30 @@ "NOT_RPYTHON" pass +class DummyGC(GCBase): + _alloc_flavor_ = "raw" + + def __init__(self, dummy=None, get_roots=None): + self.get_roots = get_roots + self.set_query_functions(None, None, None, None, None, None, None) + + def malloc(self, typeid, length=0): + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + size += length * self.varsize_item_sizes(typeid) + return raw_malloc(size) + + def collect(self): + self.get_roots() #this is there so that the annotator thinks get_roots is a function + + def size_gc_header(self, typeid=0): + return 0 + + def init_gc_object(self, addr, typeid): + return + init_gc_object_immortal = init_gc_object + + class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Wed Oct 12 19:57:16 2005 @@ -48,7 +48,7 @@ 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): + if self._T._arrayfld is not None: addr = self._address + self._layout[self._T._arrayfld] addr.signed[0] = size else: Modified: pypy/dist/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/dist/pypy/rpython/memory/simulator.py (original) +++ pypy/dist/pypy/rpython/memory/simulator.py Wed Oct 12 19:57:16 2005 @@ -113,7 +113,8 @@ return self.blocks[mid] def malloc(self, size): - assert size > 0 + if size == 0: + size = 1 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 Wed Oct 12 19:57:16 2005 @@ -5,7 +5,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.gc import DeferredRefcountingGC, DummyGC 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 @@ -138,3 +138,22 @@ def teardown_class(cls): gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func gclltype.use_gc = cls.old + +class TestDummyGC(TestMarkSweepGC): + def setup_class(cls): + gclltype.use_gc = DummyGC + cls.old = gclltype.use_gc + def teardown_class(cls): + gclltype.use_gc = cls.old + +class TestDummyGCRunningOnLLinterp(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 = DummyGC + 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 + 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 Oct 12 19:57:16 2005 @@ -121,6 +121,11 @@ assert s1.a == 17 assert s1.rest[3].v == 5 +def test_empty_struct(): + S1 = lltype.GcStruct("s1") + s1 = malloc(S1) + assert s1 == s1 + def test_substructure_ptr(): S3 = lltype.Struct("s3", ('a', lltype.Signed)) S2 = lltype.Struct("s2", ('s3', S3), ('char', lltype.Char)) From ericvrp at codespeak.net Thu Oct 13 09:40:12 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 13 Oct 2005 09:40:12 +0200 (CEST) Subject: [pypy-svn] r18512 - pypy/dist/pypy/translator/js Message-ID: <20051013074012.E972127B47@code1.codespeak.net> Author: ericvrp Date: Thu Oct 13 09:40:11 2005 New Revision: 18512 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py Log: Fixed setfield Converted some casts to javascript syntax [79 pass, 84 failed] Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Thu Oct 13 09:40:11 2005 @@ -109,21 +109,22 @@ return "{ int, [%s x %s] }" % (arraylen, typeval) def get_ref(self): + return self.ref #typeval = self.db.repr_type(lltype.typeOf(self.value)) #ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), self.ref, typeval) - p, c = lltype.parentlink(self.value) - assert p is None, "child arrays are NOT needed by rtyper" + #p, c = lltype.parentlink(self.value) + #assert p is None, "child arrays are NOT needed by rtyper" #return ref - return self.ref def get_pbcref(self, toptr): - ref = self.ref - p, c = lltype.parentlink(self.value) - assert p is None, "child arrays are NOT needed by rtyper" - - fromptr = "%s*" % self.get_typerepr() - ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) - return ref + return self.ref + #ref = self.ref + #p, c = lltype.parentlink(self.value) + #assert p is None, "child arrays are NOT needed by rtyper" + # + #fromptr = "%s*" % self.get_typerepr() + #ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) + #return ref def get_childref(self, index): return "getelementptr(%s* %s, int 0, uint 1, int %s)" %( Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Thu Oct 13 09:40:11 2005 @@ -82,7 +82,8 @@ #self.comment('target.inputargs=%s, args=%s, targetblock=%d' % (exit.target.inputargs, exit.args, targetblock), indentation_level) for i, exitarg in enumerate(exit.args): dest = str(exit.target.inputargs[i]) - src = str(exitarg) + #src = str(exitarg) + src = str(self.js.db.repr_arg(exitarg)) if src == 'False': src = 'false' elif src == 'True': Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Thu Oct 13 09:40:11 2005 @@ -213,7 +213,7 @@ return self.obj2node.itervalues() # __________________________________________________________ - # Representing variables and constants in LLVM source code + # Representing variables and constants in Javascript source code def repr_arg(self, arg): if isinstance(arg, Constant): Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Thu Oct 13 09:40:11 2005 @@ -407,39 +407,27 @@ def getfield(self, op): tmpvar = self.db.repr_tmpvar() struct, structtype = self.db.repr_argwithtype(op.args[0]) - 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) - self.codewriter.comment('XXX getfield') - self.codewriter.load(targetvar, struct, (index,)) + self.codewriter.append('%s = %s.%s' % (targetvar, struct, op.args[1].value)) #XXX move to codewriter else: self._skipped(op) def getsubstruct(self, op): struct, structtype = self.db.repr_argwithtype(op.args[0]) - index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO) + #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" - self.codewriter.getelementptr(targetvar, structtype, - struct, ("uint", index)) + #targettype = self.db.repr_arg_type(op.result) + #assert targettype != "void" + self.codewriter.append('%s = %s.%s' % (targetvar, struct, op.args[1].value)) #XXX move to codewriter + #self.codewriter.getelementptr(targetvar, structtype, struct, ("uint", index)) def setfield(self, op): - tmpvar = self.db.repr_tmpvar() struct, structtype = self.db.repr_argwithtype(op.args[0]) - 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, - # ("uint", index)) - #self.codewriter.store(valuetype, valuevar, tmpvar) - self.codewriter.comment('XXX setfield') - self.codewriter.store(struct, (index,), valuevar) + self.codewriter.append('%s.%s = %s' % (struct, op.args[1].value, valuevar)) #XXX move to codewriter else: self._skipped(op) @@ -483,8 +471,9 @@ def getarraysize(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) - tmpvar = self.db.repr_tmpvar() - self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 0)) + #tmpvar = self.db.repr_tmpvar() + #self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 0)) targetvar = self.db.repr_arg(op.result) - targettype = self.db.repr_arg_type(op.result) - self.codewriter.load(targetvar, targettype, tmpvar) + #targettype = self.db.repr_arg_type(op.result) + #self.codewriter.load(targetvar, targettype, tmpvar) + self.codewriter.append('%s = %s.length' % (targetvar, array)) #XXX move to codewriter Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Thu Oct 13 09:40:11 2005 @@ -211,22 +211,24 @@ return result def get_ref(self): - if self._get_ref_cache: - return self._get_ref_cache - ref = super(StructVarsizeNode, self).get_ref() - typeval = self.db.repr_type(lltype.typeOf(self.value)) - ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), - ref, - typeval) - self._get_ref_cache = ref - return ref + return self.ref + #if self._get_ref_cache: + # return self._get_ref_cache + #ref = super(StructVarsizeNode, self).get_ref() + #typeval = self.db.repr_type(lltype.typeOf(self.value)) + #ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), + # ref, + # typeval) + #self._get_ref_cache = ref + #return ref def get_pbcref(self, toptr): """ Returns a reference as used per pbc. """ - ref = self.ref - p, c = lltype.parentlink(self.value) - 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) - return ref + return self.ref + #ref = self.ref + #p, c = lltype.parentlink(self.value) + #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) + #return ref From ale at codespeak.net Thu Oct 13 11:45:47 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Thu, 13 Oct 2005 11:45:47 +0200 (CEST) Subject: [pypy-svn] r18513 - pypy/extradoc/sprintinfo/paris Message-ID: <20051013094547.0D53727B48@code1.codespeak.net> Author: ale Date: Thu Oct 13 11:45:45 2005 New Revision: 18513 Added: pypy/extradoc/sprintinfo/paris/wp9_10_plan.txt Log: added a first planning document for WP9 and WP10 Added: pypy/extradoc/sprintinfo/paris/wp9_10_plan.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris/wp9_10_plan.txt Thu Oct 13 11:45:45 2005 @@ -0,0 +1,51 @@ +Preliminary plan for WP9 and WP10 +================================= + +WP9 Logic Programming and Semantic Web +-------------------------------------- + +Motivations: + - logic programming is one of the few missing programming paradigm in Python + - this way of programming greatly benefits from multiple threads/coroutines and can be + simplified using a few extra language constructs + - among the domains benifiting most from logic programming are most AI engines + (prolog, implementing OWL, SQL like languages) + +Tasks: + + - Add hooks to the parser/compiler allowing syntax modifications at runtime (Logilab) + + - Investigate using continuations to implement blocking on undefined Logic variables (DFKI, Logilab) + + - Investigate adding prolog style logic constructs + + - Investigate different search algorithmes to solve logic problems + + - Implement OWL parser/inferer on top of logic constructs (DFKI) + + + +Milestones: + + - Implement a subset of prolog + + - OWL parser based on logilab.constraint integrated with rdflib + + - Constraint solving on top of continuations + + +WP10 Aspect Oriented Programming +-------------------------------- + +Motivations: + - AOP is a way to describe and implements plugging of software behavior on specific + parts of a program + - The thunk object space is a trivial example of applying an aspect to a regular object space + +Tasks: + + - Implement Aspects on AST nodes (using hooks from WP09) + - formally describe a node selection/transformation mechanism + + + From arigo at codespeak.net Thu Oct 13 13:13:49 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Oct 2005 13:13:49 +0200 (CEST) Subject: [pypy-svn] r18515 - pypy/dist/pypy/translator/c/test Message-ID: <20051013111349.2B3B727B47@code1.codespeak.net> Author: arigo Date: Thu Oct 13 13:13:46 2005 New Revision: 18515 Modified: pypy/dist/pypy/translator/c/test/test_standalone.py Log: remove unused keyword argument. Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Thu Oct 13 13:13:46 2005 @@ -1,6 +1,5 @@ from pypy.translator.translator import Translator from pypy.translator.tool.cbuild import build_executable -from pypy.translator.transform import insert_stackcheck from pypy.annotation.model import SomeList, SomeString from pypy.annotation.listdef import ListDef from pypy.rpython.objectmodel import stack_unwind, stack_frames_depth, stack_too_big @@ -124,7 +123,7 @@ -def wrap_stackless_function(fn, stackcheck=False): +def wrap_stackless_function(fn): def entry_point(argv): os.write(1, str(fn())+"\n") return 0 @@ -155,5 +154,5 @@ def fn(): return f(10**6) - data = wrap_stackless_function(fn, stackcheck=True) + data = wrap_stackless_function(fn) assert int(data.strip()) == 704 From mwh at codespeak.net Thu Oct 13 13:44:55 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 13 Oct 2005 13:44:55 +0200 (CEST) Subject: [pypy-svn] r18516 - pypy/dist/pypy/translator/asm Message-ID: <20051013114455.4603227B45@code1.codespeak.net> Author: mwh Date: Thu Oct 13 13:44:53 2005 New Revision: 18516 Removed: pypy/dist/pypy/translator/asm/regmap.py Log: (AFT) Removed redundant file regmap.py (algorithm moved to simulator.py) From hpk at codespeak.net Thu Oct 13 15:33:49 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 13 Oct 2005 15:33:49 +0200 (CEST) Subject: [pypy-svn] r18518 - pypy/extradoc/pypy.org Message-ID: <20051013133349.7854827B46@code1.codespeak.net> Author: hpk Date: Thu Oct 13 15:33:43 2005 New Revision: 18518 Modified: pypy/extradoc/pypy.org/confrest.py Log: don't point to EU-issues tracker Modified: pypy/extradoc/pypy.org/confrest.py ============================================================================== --- pypy/extradoc/pypy.org/confrest.py (original) +++ pypy/extradoc/pypy.org/confrest.py Thu Oct 13 15:33:43 2005 @@ -7,8 +7,8 @@ html.a("home", href="index.html", class_="menu"), " ", html.a("news", href="news.html", class_="menu"), " ", html.a("consortium", href="consortium.html", class_="menu"), " ", - html.a("EU-Issues", href="https://codespeak.net/issue/pypy-eu/", - class_="menu"), " ", + #html.a("EU-Issues", href="https://codespeak.net/issue/pypy-eu/", + # class_="menu"), " ", html.a("community/coding", href="http://codespeak.net/pypy/dist/pypy/doc/index.html", class_="menu"), " ", From arigo at codespeak.net Thu Oct 13 15:54:52 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 13 Oct 2005 15:54:52 +0200 (CEST) Subject: [pypy-svn] r18519 - pypy/dist/pypy/doc Message-ID: <20051013135452.D674E27B47@code1.codespeak.net> Author: arigo Date: Thu Oct 13 15:54:50 2005 New Revision: 18519 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Roughly finished the sections before "Termination". Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Thu Oct 13 15:54:50 2005 @@ -1019,9 +1019,9 @@ instances". By default, instances of some user-defined class that happens to pre-exist annotation have no constantness requirement on their own; after annotation and possibly compilation, these instances -will continue to behave as regular mutable instances of that class. -These prebuilt instances are decribed in another section (`Constant -annotations`_). However, the user program can give a hint that forces +will continue to behave as regular mutable instances of that class, +turned into mostly regular ``Inst(C)`` annotations when the annotator +encounters them. However, the user program can give a hint that forces the annotator to consider the object as a "frozen prebuilt constant". The object is then considered as a now-immutable container of attributes. It looses its object-oriented aspects and its class becomes @@ -1071,15 +1071,15 @@ program that is static enough, it must reconstruct a static structure for each class in the hierarchy. It does so by observing the usage patterns of the classes and their instances, by propagating annotations -of the form ``SomeInstance(cls)`` -- which stands for "an instance of -the class *cls* or any subclass". Instance fields are attached to a -class whenever we see that the field is being written to an instance of -this class. If the user program manipulates instances polymorphically, -the variables holding the instances will be annotated -``SomeInstance(cls)`` with some abstract base class *cls*; accessing -attributes on such generalized instances lifts the inferred attribute -declarations up to *cls*. The same technique works for inferring the -location of both fields and methods. +of the form ``Inst(cls)`` -- which stands for "an instance of the class +*cls* or any subclass". Instance fields are attached to a class +whenever we see that the field is being written to an instance of this +class. If the user program manipulates instances polymorphically, the +variables holding the instances will be annotated ``Inst(cls)`` with +some abstract base class *cls*; accessing attributes on such generalized +instances lifts the inferred attribute declarations up to *cls*. The +same technique works for inferring the location of both fields and +methods. ~~~~~~~~~~~~~~~~~~~~~~ @@ -1121,120 +1121,74 @@ E' = E union (v_C.attr ~ v_D.attr) for all D subclass of C merge_into(z, v_C.attr) -The purpose of ``lookup_filter`` is to avoid loosing precision in method -calls. Indeed, as described more precisely in `Constant annotations`_ -below, if ``attr`` names a method of the class ``C`` then the binding -``b(v_C.attr)`` is a ``Pbc`` that includes all the "potental bound -method" objects ``D.f``, for each subclass ``D`` of ``C`` where a -function ``f`` is present under the name ``attr``. - -XXX - - -if ``attr`` is a method defined on XXX:: - - lookup_filter(Pbc(set), class) = Pbc(newset) where - we only keep in newset the non-methods, and the following methods: - * the ones bound to a strict subclass of 'class', and - * among the methods bound the 'class' or superclasses, only the - one from the most derived class. - lookup_filter(NonPbcAnnotation, class) = NonPbcAnnotation - Note the similarity with the ``getitem`` and ``setitem`` of lists, in particular the usage of the auxiliary variable *z'*. -XXX - - -Constant annotations -~~~~~~~~~~~~~~~~~~~~ +The purpose of ``lookup_filter`` is to avoid loosing precision in method +calls. Indeed, if ``attr`` names a method of the class ``C`` then the +binding ``b(v_C.attr)`` is initialized to ``Pbc(m)``, where *m* is the +following set: -XXX constant arguments to operations +* for each subclass ``D`` of ``C``, if the class ``D`` introduces a method + ``attr`` implemented as, say, the function ``f``, then the "potential + bound method" object ``D.f`` belongs to *m*. +However, because of the possible identification between the variable +``v_C.attr`` and the corresponding variable ``v_B.attr`` of a +superclass, the set *m* might end up containing potential bound methods +of other unrelated subclasses of ``B``, even when performing a +``getattr`` on what we know is an instance of ``C``. The +``lookup_filter`` reverses this effect as follows:: -Draft -~~~~~ + lookup_filter(Pbc(set), C) = Pbc(newset) + lookup_filter(NonPbcAnnotation, C) = NonPbcAnnotation -:: +where the *newset* only keeps the non-methods of *set* (if any) plus the +following methods: - Char - - Inst(class) - - List(x) - - Dict(x, y) - - Tup(ann_1, ..., ann_n) - - Pbc({... a finite set ...}) - - with: None - f - class - class.f - - v_n = op(v_n1, ...) | v_n', v_n'' - - v_class.attr - - v_n: Annotation - - for each function f: - arg_f_1 ... arg_f_n - returnvar_f - - - E: eq rel on V - b: V->A - V: set of variables - A: fixed lattice of the above annotation terms +* the ones bound to a strict subclass of ``C``, plus - - z=getattr(x,attr) | z', b(x)=Inst(A) - --------------------------------------------------------------------- - E' = E union (A.attr ~ A'.attr) for all A' subclass of A - E' = E union (z' ~ A.attr) - b' = b with (z->lookup_filter(b(z'), A)) +* among the methods bound to ``C`` or superclasses of ``C``, only the + one from the most derived class. - setattr(x,attr,z), b(x)=Inst(A) - --------------------------------------------------------------------- - assert b(z) is not a Pbc containing methods - E' = E union (A.attr ~ A'.attr) for all A' subclass of A - merge_into(z, A.attr) +Calls +~~~~~ +The ``Pbc`` annotations regroup (among others) all user-defined callable +objects: functions, methods and classes. A call in the user program +turns into a ``simplecall`` operation whose first argument is the object +to call. Here is the corresponding rule -- regrouping all cases because +the same ``Pbc(set)`` could mix several kinds of callables:: z=simplecall(x,y1,...,yn), b(x)=Pbc(set) --------------------------------------------------------------------- for each c in set: if c is a function: - E' = E union (z~returnvar_c) + E' = E union (z ~ returnvar_c) merge_into(y1, arg_c_1) ... merge_into(yn, arg_c_n) if c is a class: let f = c.__init__ - b' = b with (z->b(z)\/Inst(c)) - b' = b with (arg_f_1->b(arg_f_1)\/Inst(c)) + b' = b with (z -> b(z) \/ Inst(c)) + and (arg_f_1 -> b(arg_f_1) \/ Inst(c)) merge_into(y1, arg_f_2) ... merge_into(yn, arg_f_(n+1)) if c is a method: let class.f = c - E' = E union (z~returnvar_f) - b' = b with (arg_f_1->b(arg_f_1)\/Inst(class)) + E' = E union (z ~ returnvar_f) + b' = b with (arg_f_1 -> b(arg_f_1) \/ Inst(class)) merge_into(y1, arg_f_2) ... merge_into(yn, arg_f_(n+1)) - - lookup_filter(Pbc(set), class) = Pbc(newset) where - we only keep in newset the non-methods, and the following methods: - * the ones bound to a strict subclass of 'class', and - * among the methods bound the 'class' or superclasses, only the - one from the most derived class. - lookup_filter(NonPbcAnnotation, class) = NonPbcAnnotation +Calling a class returns an instance and flows the annotations into the +contructor ``__init__`` of the class. Calling a method inserts the +instance annotation as the first argument of the underlying function +(the annotation is exactly ``Inst(C)`` for the class ``C`` in which the +method is found). Termination @@ -1258,6 +1212,9 @@ to prove that there is no infinite ascending chain, which is enough to guarantee termination. +Additionally, an important property of ``lookup_filter`` is to be +monotonic: XXX + Non-static aspects ~~~~~~~~~~~~~~~~~~ From boria at codespeak.net Thu Oct 13 16:47:44 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Thu, 13 Oct 2005 16:47:44 +0200 (CEST) Subject: [pypy-svn] r18520 - in pypy/branch/hl-backend/pypy/rpython: . lltypesystem Message-ID: <20051013144744.D3C2327B44@code1.codespeak.net> Author: boria Date: Thu Oct 13 16:47:44 2005 New Revision: 18520 Added: pypy/branch/hl-backend/pypy/rpython/lltypesystem/ (props changed) pypy/branch/hl-backend/pypy/rpython/lltypesystem/__init__.py (contents, props changed) pypy/branch/hl-backend/pypy/rpython/lltypesystem/exceptiondata.py - copied, changed from r18504, pypy/branch/hl-backend/pypy/rpython/exceptiondata.py pypy/branch/hl-backend/pypy/rpython/lltypesystem/lltype.py - copied, changed from r18479, pypy/branch/hl-backend/pypy/rpython/lltype.py pypy/branch/hl-backend/pypy/rpython/lltypesystem/rbuiltin.py - copied, changed from r18504, pypy/branch/hl-backend/pypy/rpython/rbuiltin.py pypy/branch/hl-backend/pypy/rpython/lltypesystem/rclass.py - copied, changed from r18479, pypy/branch/hl-backend/pypy/rpython/rclass.py Removed: pypy/branch/hl-backend/pypy/rpython/exceptiondata.py Modified: pypy/branch/hl-backend/pypy/rpython/lltype.py pypy/branch/hl-backend/pypy/rpython/rbuiltin.py pypy/branch/hl-backend/pypy/rpython/rclass.py pypy/branch/hl-backend/pypy/rpython/rlist.py pypy/branch/hl-backend/pypy/rpython/rpbc.py pypy/branch/hl-backend/pypy/rpython/rstr.py pypy/branch/hl-backend/pypy/rpython/rtyper.py pypy/branch/hl-backend/pypy/rpython/typesystem.py Log: (Samuele, Boris) * Continuing work on decoupling RTyper from lltypes. * Lazy imports in typesystem.py to avoid circular import problems. * Refactor rclass.py and rbuiltin.py into common and lltype-specific parts. * Several tests still failing in rpython/test/ due to rpbc.py. Modified: pypy/branch/hl-backend/pypy/rpython/lltype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/lltype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/lltype.py Thu Oct 13 16:47:44 2005 @@ -1,965 +1 @@ -import weakref, operator -import py -from pypy.rpython.rarithmetic import r_uint -from pypy.tool.uid import Hashable -from pypy.tool.tls import tlsobject -from types import NoneType - -log = py.log.Producer('lltype') - -TLS = tlsobject() - -def saferecursive(func, defl): - def safe(*args): - try: - seeing = TLS.seeing - except AttributeError: - seeing = TLS.seeing = {} - seeingkey = tuple([func] + [id(arg) for arg in args]) - if seeingkey in seeing: - return defl - seeing[seeingkey] = True - try: - return func(*args) - finally: - del seeing[seeingkey] - return safe - -#safe_equal = saferecursive(operator.eq, True) -def safe_equal(x, y): - # a specialized version for performance - try: - seeing = TLS.seeing_eq - except AttributeError: - seeing = TLS.seeing_eq = {} - seeingkey = (id(x), id(y)) - if seeingkey in seeing: - return True - seeing[seeingkey] = True - try: - return x == y - finally: - del seeing[seeingkey] - - -class frozendict(dict): - - def __hash__(self): - items = self.items() - items.sort() - return hash(tuple(items)) - - -class LowLevelType(object): - # the following line prevents '__cached_hash' to be in the __dict__ of - # the instance, which is needed for __eq__() and __hash__() to work. - __slots__ = ['__dict__', '__cached_hash'] - - def __eq__(self, other): - return self.__class__ is other.__class__ and ( - self is other or safe_equal(self.__dict__, other.__dict__)) - - def __ne__(self, other): - return not (self == other) - - def __hash__(self): - # cannot use saferecursive() -- see test_lltype.test_hash(). - # NB. the __cached_hash should neither be used nor updated - # if we enter with hash_level > 0, because the computed - # __hash__ can be different in this situation. - hash_level = 0 - try: - hash_level = TLS.nested_hash_level - if hash_level == 0: - return self.__cached_hash - except AttributeError: - pass - if hash_level >= 3: - return 0 - items = self.__dict__.items() - items.sort() - TLS.nested_hash_level = hash_level + 1 - try: - result = hash((self.__class__,) + tuple(items)) - finally: - TLS.nested_hash_level = hash_level - if hash_level == 0: - self.__cached_hash = result - return result - - # due to this dynamic hash value, we should forbid - # pickling, until we have an algorithm for that. - # but we just provide a tag for external help. - __hash_is_not_constant__ = True - - def __repr__(self): - return '<%s>' % (self,) - - def __str__(self): - return self.__class__.__name__ - - def _short_name(self): - return str(self) - - def _defl(self, parent=None, parentindex=None): - raise NotImplementedError - - def _freeze_(self): - return True - - def _inline_is_varsize(self, last): - return False - - def _is_atomic(self): - return False - - def _is_varsize(self): - return False - - -class ContainerType(LowLevelType): - def _gcstatus(self): - return isinstance(self, GC_CONTAINER) - - 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 - flds = {} - names = [] - self._arrayfld = None - for name, typ in fields: - if name.startswith('_'): - raise NameError, ("%s: field name %r should not start with " - "an underscore" % (self._name, name,)) - names.append(name) - if name in flds: - raise TypeError("%s: repeated field name" % self._name) - flds[name] = typ - if isinstance(typ, GC_CONTAINER): - if name == fields[0][0] and isinstance(self, GC_CONTAINER): - pass # can inline a GC_CONTAINER as 1st field of GcStruct - else: - raise TypeError("%s: cannot inline GC container %r" % ( - self._name, typ)) - - # look if we have an inlined variable-sized array as the last field - if fields: - for name, typ in fields[:-1]: - typ._inline_is_varsize(False) - first = False - name, typ = fields[-1] - if typ._inline_is_varsize(True): - self._arrayfld = name - self._flds = frozendict(flds) - self._names = tuple(names) - - def _first_struct(self): - if self._names: - first = self._names[0] - FIRSTTYPE = self._flds[first] - if isinstance(FIRSTTYPE, Struct) and self._gcstatus() == FIRSTTYPE._gcstatus(): - return first, FIRSTTYPE - return None, None - - def _inline_is_varsize(self, last): - if self._arrayfld: - raise TypeError("cannot inline a var-sized struct " - "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 _is_varsize(self): - return self._arrayfld is not None - - def __getattr__(self, name): - try: - return self._flds[name] - except KeyError: - raise AttributeError, 'struct %s has no field %r' % (self._name, - name) - - def _names_without_voids(self): - names_without_voids = [name for name in self._names if self._flds[name] is not Void] - return names_without_voids - - def _str_fields_without_voids(self): - return ', '.join(['%s: %s' % (name, self._flds[name]) - for name in self._names_without_voids(False)]) - _str_fields_without_voids = saferecursive(_str_fields_without_voids, '...') - - def _str_without_voids(self): - 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]) - _str_fields = saferecursive(_str_fields, '...') - - def __str__(self): - return "%s %s { %s }" % (self.__class__.__name__, - self._name, self._str_fields()) - - def _short_name(self): - return "%s %s" % (self.__class__.__name__, self._name) - - def _defl(self, parent=None, parentindex=None): - return _struct(self, parent=parent, parentindex=parentindex) - - def _container_example(self): - if self._arrayfld is None: - n = None - else: - n = 1 - return _struct(self, n) - -class GcStruct(Struct): - _runtime_type_info = None - - def _attach_runtime_type_info_funcptr(self, funcptr): - if self._runtime_type_info is None: - self._runtime_type_info = opaqueptr(RuntimeTypeInfo, name=self._name, about=self)._obj - if funcptr is not None: - T = typeOf(funcptr) - if (not isinstance(T, Ptr) or - not isinstance(T.TO, FuncType) or - len(T.TO.ARGS) != 1 or - T.TO.RESULT != Ptr(RuntimeTypeInfo) or - castable(T.TO.ARGS[0], Ptr(self)) < 0): - raise TypeError("expected a runtime type info function " - "implementation, got: %s" % funcptr) - self._runtime_type_info.query_funcptr = funcptr - -class Array(ContainerType): - __name__ = 'array' - _anonym_struct = False - - def __init__(self, *fields): - if len(fields) == 1 and isinstance(fields[0], LowLevelType): - self.OF = fields[0] - else: - self.OF = Struct("", *fields) - self._anonym_struct = True - if isinstance(self.OF, GcStruct): - raise TypeError("cannot have a GC structure as array item type") - self.OF._inline_is_varsize(False) - - def _inline_is_varsize(self, last): - if not last: - raise TypeError("cannot inline an array in another container" - " unless as the last field of a structure") - return True - - def _is_atomic(self): - return self.OF._is_atomic() - - def _is_varsize(self): - return True - - def _str_fields(self): - if isinstance(self.OF, Struct): - of = self.OF - if self._anonym_struct: - return "{ %s }" % of._str_fields() - else: - return "%s { %s }" % (of._name, of._str_fields()) - else: - return self.OF - - def __str__(self): - return "%s of %s " % (self.__class__.__name__, - self._str_fields(),) - - def _short_name(self): - return "%s %s" % (self.__class__.__name__, - self.OF._short_name(),) - - def _container_example(self): - return _array(self, 1) - -class GcArray(Array): - def _inline_is_varsize(self, last): - raise TypeError("cannot inline a GC array inside a structure") - -class FuncType(ContainerType): - __name__ = 'func' - def __init__(self, args, result): - for arg in args: - assert isinstance(arg, LowLevelType) - if isinstance(arg, ContainerType): - raise TypeError, "function arguments can only be primitives or pointers" - self.ARGS = tuple(args) - assert isinstance(result, LowLevelType) - if isinstance(result, ContainerType): - raise TypeError, "function result can only be primitive or pointer" - self.RESULT = result - - def __str__(self): - args = ', '.join(map(str, self.ARGS)) - return "Func ( %s ) -> %s" % (args, self.RESULT) - - def _short_name(self): - args = ', '.join([ARG._short_name() for ARG in self.ARGS]) - return "Func(%s)->%s" % (args, self.RESULT._short_name) - - def _container_example(self): - def ex(*args): - return self.RESULT._defl() - return _func(self, _callable=ex) - - def _trueargs(self): - return [arg for arg in self.ARGS if arg is not Void] - - -class OpaqueType(ContainerType): - - def __init__(self, tag): - self.tag = tag - self.__name__ = tag - - 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 _opaque(self, parent=parent, parentindex=parentindex) - -RuntimeTypeInfo = OpaqueType("RuntimeTypeInfo") - -class PyObjectType(ContainerType): - __name__ = 'PyObject' - def __str__(self): - return "PyObject" -PyObject = PyObjectType() - -class ForwardReference(ContainerType): - def become(self, realcontainertype): - if not isinstance(realcontainertype, ContainerType): - raise TypeError("ForwardReference can only be to a container, " - "not %r" % (realcontainertype,)) - self.__class__ = realcontainertype.__class__ - self.__dict__ = realcontainertype.__dict__ - - def __hash__(self): - raise TypeError("%r object is not hashable" % self.__class__.__name__) - -class GcForwardReference(ForwardReference): - def become(self, realcontainertype): - if not isinstance(realcontainertype, GC_CONTAINER): - raise TypeError("GcForwardReference can only be to GcStruct or " - "GcArray, not %r" % (realcontainertype,)) - self.__class__ = realcontainertype.__class__ - self.__dict__ = realcontainertype.__dict__ - -GC_CONTAINER = (GcStruct, GcArray, PyObjectType, GcForwardReference) - - -class Primitive(LowLevelType): - def __init__(self, name, default): - self._name = self.__name__ = name - self._default = default - - def __str__(self): - return self._name - - def _defl(self, parent=None, parentindex=None): - return self._default - - def _is_atomic(self): - return True - - _example = _defl - - -Signed = Primitive("Signed", 0) -Unsigned = Primitive("Unsigned", r_uint(0)) -Float = Primitive("Float", 0.0) -Char = Primitive("Char", '\x00') -Bool = Primitive("Bool", False) -Void = Primitive("Void", None) -UniChar = Primitive("UniChar", u'\x00') - - -class Ptr(LowLevelType): - __name__ = property(lambda self: '%sPtr' % self.TO.__name__) - - def __init__(self, TO): - if not isinstance(TO, ContainerType): - raise TypeError, ("can only point to a Container type, " - "not to %s" % (TO,)) - self.TO = TO - - def _needsgc(self): - return self.TO._gcstatus() - - def __str__(self): - return '* %s' % (self.TO, ) - - def _short_name(self): - return 'Ptr %s' % (self.TO._short_name(), ) - - def _is_atomic(self): - return not self.TO._gcstatus() - - def _defl(self, parent=None, parentindex=None): - return _ptr(self, None) - - def _example(self): - o = self.TO._container_example() - return _ptr(self, o, solid=True) - - -# ____________________________________________________________ - - -def typeOf(val): - try: - return val._TYPE - except AttributeError: - tp = type(val) - if tp is NoneType: - return Void # maybe - if tp is int: - return Signed - if tp is bool: - return Bool - if tp is r_uint: - return Unsigned - if tp is float: - return Float - if tp is str: - assert len(val) == 1 - return Char - if tp is unicode: - assert len(val) == 1 - return UniChar - raise TypeError("typeOf(%r object)" % (tp.__name__,)) - -class InvalidCast(TypeError): - pass - -def _castdepth(OUTSIDE, INSIDE): - if OUTSIDE == INSIDE: - return 0 - dwn = 0 - while True: - first, FIRSTTYPE = OUTSIDE._first_struct() - if first is None: - return -1 - dwn += 1 - if FIRSTTYPE == INSIDE: - return dwn - OUTSIDE = getattr(OUTSIDE, first) - -def castable(PTRTYPE, CURTYPE): - if CURTYPE._needsgc() != PTRTYPE._needsgc(): - raise TypeError("cast_pointer() cannot change the gc status: %s to %s" - % (CURTYPE, PTRTYPE)) - if (not isinstance(CURTYPE.TO, Struct) or - not isinstance(PTRTYPE.TO, Struct)): - raise InvalidCast(CURTYPE, PTRTYPE) - CURSTRUC = CURTYPE.TO - PTRSTRUC = PTRTYPE.TO - d = _castdepth(CURSTRUC, PTRSTRUC) - if d >= 0: - return d - u = _castdepth(PTRSTRUC, CURSTRUC) - if u == -1: - raise InvalidCast(CURTYPE, PTRTYPE) - return -u - -def cast_pointer(PTRTYPE, ptr): - if not isinstance(ptr, _ptr) or not isinstance(PTRTYPE, Ptr): - raise TypeError, "can only cast pointers to other pointers" - CURTYPE = ptr._TYPE - down_or_up = castable(PTRTYPE, CURTYPE) - if down_or_up == 0: - return ptr - if not ptr: # null pointer cast - return PTRTYPE._defl() - if down_or_up > 0: - p = ptr - while down_or_up: - p = getattr(p, typeOf(p).TO._names[0]) - down_or_up -= 1 - return _ptr(PTRTYPE, p._obj) - u = -down_or_up - struc = ptr._obj - while u: - parent = struc._parentstructure() - if parent is None: - raise RuntimeError("widening to trash: %r" % ptr) - PARENTTYPE = struc._parent_type - if getattr(parent, PARENTTYPE._names[0]) is not struc: - raise InvalidCast(CURTYPE, PTRTYPE) # xxx different exception perhaps? - struc = parent - u -= 1 - if PARENTTYPE != PTRTYPE.TO: - raise TypeError("widening %r inside %r instead of %r" % (CURTYPE, PARENTTYPE, PTRTYPE.TO)) - return _ptr(PTRTYPE, struc) - -def _expose(val): - """XXX A nice docstring here""" - T = typeOf(val) - if isinstance(T, ContainerType): - val = _ptr(Ptr(T), val) - return val - -def parentlink(container): - parent = container._parentstructure() - if parent is not None: - return parent, container._parent_index -## if isinstance(parent, _struct): -## for name in parent._TYPE._names: -## if getattr(parent, name) is container: -## return parent, name -## raise RuntimeError("lost ourselves") -## if isinstance(parent, _array): -## raise TypeError("cannot fish a pointer to an array item or an " -## "inlined substructure of it") -## raise AssertionError("don't know about %r" % (parent,)) - else: - return None, None - - -class _ptr(object): - __slots__ = ('_TYPE', '_T', - '_weak', '_solid', - '_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_solid(self, solid): - _ptr._solid.__set__(self, solid) - - 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, solid=False): - self._set_TYPE(TYPE) - self._set_T(TYPE.TO) - self._set_weak(False) - self._setobj(pointing_to, solid) - - def __eq__(self, other): - if not isinstance(other, _ptr): - 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._obj is other._obj - - def __ne__(self, other): - return not (self == other) - - def __hash__(self): - raise TypeError("pointer objects are not hashable") - - def __nonzero__(self): - return self._obj is not None - - # _setobj, _getobj and _obj0 are really _internal_ implementations details of _ptr, - # use _obj if necessary instead ! - def _setobj(self, pointing_to, solid=False): - if pointing_to is None: - obj0 = None - elif solid or isinstance(self._T, (GC_CONTAINER, FuncType)): - obj0 = pointing_to - else: - self._set_weak(True) - obj0 = weakref.ref(pointing_to) - self._set_solid(solid) - self._set_obj0(obj0) - - def _getobj(self): - obj = self._obj0 - if obj is not None and self._weak: - obj = obj() - if obj is None: - raise RuntimeError("accessing already garbage collected %r" - % (self._T,)) - obj._check() - return obj - _obj = property(_getobj) - - def __getattr__(self, field_name): # ! can only return basic or ptr ! - if isinstance(self._T, Struct): - if field_name in self._T._flds: - o = getattr(self._obj, field_name) - return _expose(o) - raise AttributeError("%r instance has no field %r" % (self._T, - field_name)) - - #def _setfirst(self, p): - # if isinstance(self._T, Struct) and self._T._names: - # if not isinstance(p, _ptr) or not isinstance(p._obj, _struct): - # raise InvalidCast(typeOf(p), typeOf(self)) - # field_name = self._T._names[0] - # T1 = self._T._flds[field_name] - # T2 = typeOf(p._obj) - # if T1 != T2: - # raise InvalidCast(typeOf(p), typeOf(self)) - # setattr(self._obj, field_name, p._obj) - # p._obj._setparentstructure(self._obj, 0) - # return - # raise TypeError("%r instance has no first field" % (self._T,)) - - def __setattr__(self, field_name, val): - if isinstance(self._T, Struct): - if field_name in self._T._flds: - T1 = self._T._flds[field_name] - T2 = typeOf(val) - if T1 == T2: - setattr(self._obj, field_name, val) - else: - raise TypeError("%r instance field %r:\n" - "expects %r\n" - " got %r" % (self._T, field_name, T1, T2)) - return - raise AttributeError("%r instance has no field %r" % (self._T, - field_name)) - - def __getitem__(self, i): # ! can only return basic or ptr ! - if isinstance(self._T, Array): - if not (0 <= i < len(self._obj.items)): - raise IndexError("array index out of bounds") - o = self._obj.items[i] - return _expose(o) - raise TypeError("%r instance is not an array" % (self._T,)) - - def __setitem__(self, i, val): - if isinstance(self._T, Array): - T1 = self._T.OF - if isinstance(T1, ContainerType): - raise TypeError("cannot directly assign to container array items") - T2 = typeOf(val) - if T2 != T1: - raise TypeError("%r items:\n" - "expect %r\n" - " got %r" % (self._T, T1, T2)) - if not (0 <= i < len(self._obj.items)): - raise IndexError("array index out of bounds") - self._obj.items[i] = val - return - raise TypeError("%r instance is not an array" % (self._T,)) - - def __len__(self): - if isinstance(self._T, Array): - return len(self._obj.items) - raise TypeError("%r instance is not an array" % (self._T,)) - - def __repr__(self): - return '<%s>' % (self,) - - def __str__(self): - return '* %s' % (self._obj, ) - - def __call__(self, *args): - if isinstance(self._T, 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 typeOf(a) != ARG: - raise TypeError,"calling %r with wrong argument types: %r" % (self._T, args) - callb = self._obj._callable - if callb is None: - raise RuntimeError,"calling undefined function" - return callb(*args) - raise TypeError("%r instance is not a function" % (self._T,)) - -assert not '__dict__' in dir(_ptr) - -class _parentable(object): - _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) - self._parent_index = parentindex - if (isinstance(self._parent_type, Struct) - and parentindex == self._parent_type._names[0] - and self._TYPE._gcstatus() == typeOf(parent)._gcstatus()): - # keep strong reference to parent, we share the same allocation - self._keepparent = parent - - def _parentstructure(self): - if self._wrparent is not None: - parent = self._wrparent() - if parent is None: - raise RuntimeError("accessing sub%s %r,\n" - "but already garbage collected parent %r" - % (self._kind, self, self._parent_type)) - parent._check() - return parent - return None - - 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): - _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: - raise TypeError("%r is variable-sized" % (TYPE,)) - for fld, typ in TYPE._flds.items(): - if fld == TYPE._arrayfld: - value = _array(typ, n, parent=self, parentindex=fld) - else: - value = typ._defl(parent=self, parentindex=fld) - setattr(self, fld, value) - if parent is not None: - self._setparentstructure(parent, parentindex) - - def __repr__(self): - return '<%s>' % (self,) - - def _str_fields(self): - fields = [] - for name in self._TYPE._names: - T = self._TYPE._flds[name] - if isinstance(T, Primitive): - reprvalue = repr(getattr(self, name)) - else: - reprvalue = '...' - fields.append('%s=%s' % (name, reprvalue)) - return ', '.join(fields) - - def __str__(self): - return 'struct %s { %s }' % (self._TYPE._name, self._str_fields()) - -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" - _parentable.__init__(self, TYPE) - self.items = [TYPE.OF._defl(parent=self, parentindex=j) - for j in range(n)] - if parent is not None: - self._setparentstructure(parent, parentindex) - - def __repr__(self): - return '<%s>' % (self,) - - def _str_item(self, item): - if isinstance(self._TYPE.OF, Struct): - of = self._TYPE.OF - if self._TYPE._anonym_struct: - return "{%s}" % item._str_fields() - else: - return "%s {%s}" % (of._name, item._str_fields()) - else: - return item - - def __str__(self): - 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 - self._name = "?" - self._callable = None - self.__dict__.update(attrs) - - def _parentstructure(self): - return None - - def _check(self): - pass - - def __repr__(self): - return '<%s>' % (self,) - - def __str__(self): - return "fn %s" % self._name - - def __eq__(self, other): - return (self.__class__ is other.__class__ and - self.__dict__ == other.__dict__) - - def __ne__(self, other): - return not (self == other) - - def __hash__(self): - return hash(frozendict(self.__dict__)) - -class _opaque(_parentable): - def __init__(self, TYPE, parent=None, parentindex=None, **attrs): - _parentable.__init__(self, TYPE) - self._name = "?" - self.__dict__.update(attrs) - if parent is not None: - self._setparentstructure(parent, parentindex) - - def __repr__(self): - return '<%s>' % (self,) - - def __str__(self): - return "%s %s" % (self._TYPE.__name__, self._name) - - -class _pyobject(Hashable): - __slots__ = [] # or we get in trouble with pickling - - _TYPE = PyObject - - def _parentstructure(self): - return None - - def _check(self): - pass - - def __repr__(self): - return '<%s>' % (self,) - - def __str__(self): - return "pyobject %s" % (super(_pyobject, self).__str__(),) - - -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 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): - raise TypeError, "functionptr() for FuncTypes only" - try: - hash(tuple(attrs.items())) - except TypeError: - raise TypeError("'%r' must be hashable"%attrs) - o = _func(TYPE, _name=name, **attrs) - return _ptr(Ptr(TYPE), o) - -def nullptr(T): - return Ptr(T)._defl() - -def opaqueptr(TYPE, name, **attrs): - if not isinstance(TYPE, OpaqueType): - raise TypeError, "opaqueptr() for OpaqueTypes only" - o = _opaque(TYPE, _name=name, **attrs) - return _ptr(Ptr(TYPE), o, solid=attrs.get('immortal', True)) - -def pyobjectptr(obj): - 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 - GCSTRUCT._attach_runtime_type_info_funcptr(funcptr) - return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info) - -def getRuntimeTypeInfo(GCSTRUCT): - if not isinstance(GCSTRUCT, GcStruct): - raise TypeError, "expected a GcStruct: %s" % GCSTRUCT - if GCSTRUCT._runtime_type_info is None: - raise ValueError, "no attached runtime type info for %s" % GCSTRUCT - return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info) - -def runtime_type_info(p): - T = typeOf(p) - if not isinstance(T, Ptr) or not isinstance(T.TO, GcStruct): - raise TypeError, "runtime_type_info on non-GcStruct pointer: %s" % p - top_parent = struct = p._obj - while True: - parent = top_parent._parentstructure() - if parent is None: - break - top_parent = parent - result = getRuntimeTypeInfo(top_parent._TYPE) - static_info = getRuntimeTypeInfo(T.TO) - query_funcptr = getattr(static_info._obj, 'query_funcptr', None) - if query_funcptr is not None: - T = typeOf(query_funcptr).TO.ARGS[0] - result2 = query_funcptr(cast_pointer(T, p)) - if result != result2: - raise RuntimeError, ("runtime type-info function for %s:\n" - " returned: %s,\n" - "should have been: %s" % (p, result2, result)) - return result - +from pypy.rpython.lltypesystem.lltype import * # FIXME Added: pypy/branch/hl-backend/pypy/rpython/lltypesystem/__init__.py ============================================================================== Modified: pypy/branch/hl-backend/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rbuiltin.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rbuiltin.py Thu Oct 13 16:47:44 2005 @@ -10,7 +10,6 @@ from pypy.rpython.rfloat import float_repr, FloatRepr from pypy.rpython.rbool import bool_repr from pypy.rpython.rdict import rtype_r_dict -from pypy.rpython import rclass from pypy.tool import sourcetools class __extend__(annmodel.SomeBuiltin): @@ -55,8 +54,12 @@ try: bltintyper = BUILTIN_TYPER[self.builtinfunc] except KeyError: - raise TyperError("don't know about built-in function %r" % ( - self.builtinfunc,)) + try: + rtyper = hop.rtyper + bltintyper = rtyper.type_system.BUILTIN_TYPER[self.builtinfunc] + except KeyError: + raise TyperError("don't know about built-in function %r" % ( + self.builtinfunc,)) hop2 = hop.copy() hop2.r_s_popfirstarg() return bltintyper(hop2) @@ -129,36 +132,6 @@ def rtype_builtin_list(hop): return hop.args_r[0].rtype_bltn_list(hop) -def rtype_builtin_isinstance(hop): - if hop.s_result.is_constant(): - return hop.inputconst(lltype.Bool, hop.s_result.const) - if hop.args_r[0] == pyobj_repr or hop.args_r[1] == pyobj_repr: - v_obj, v_typ = hop.inputargs(pyobj_repr, pyobj_repr) - c = hop.inputconst(pyobj_repr, isinstance) - v = hop.genop('simple_call', [c, v_obj, v_typ], resulttype = pyobj_repr) - return hop.llops.convertvar(v, pyobj_repr, bool_repr) - - if hop.args_s[1].is_constant() and hop.args_s[1].const == list: - if hop.args_s[0].knowntype != list: - raise TyperError("isinstance(x, list) expects x to be known statically to be a list or None") - rlist = hop.args_r[0] - vlist = hop.inputarg(rlist, arg=0) - cnone = hop.inputconst(rlist, None) - return hop.genop('ptr_ne', [vlist, cnone], resulttype=lltype.Bool) - - 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) - if isinstance(v_cls, Constant): - minid = hop.inputconst(lltype.Signed, v_cls.value.subclassrange_min) - maxid = hop.inputconst(lltype.Signed, v_cls.value.subclassrange_max) - return hop.gendirectcall(rclass.ll_isinstance_const, v_obj, minid, - maxid) - else: - return hop.gendirectcall(rclass.ll_isinstance, v_obj, v_cls) - #def rtype_builtin_range(hop): see rrange.py #def rtype_builtin_xrange(hop): see rrange.py @@ -212,24 +185,6 @@ v_errno = hop.inputarg(lltype.Signed, arg=1) r_self.setfield(v_self, 'errno', v_errno, hop.llops) -def ll_instantiate(typeptr): - my_instantiate = typeptr.instantiate - return my_instantiate() - -def rtype_instantiate(hop): - s_class = hop.args_s[0] - assert isinstance(s_class, annmodel.SomePBC) - if len(s_class.prebuiltinstances) != 1: - # instantiate() on a variable class - vtypeptr, = hop.inputargs(rclass.get_type_repr(hop.rtyper)) - v_inst = hop.gendirectcall(ll_instantiate, vtypeptr) - return hop.genop('cast_pointer', [v_inst], # v_type implicit in r_result - resulttype = hop.r_result.lowleveltype) - - - klass = s_class.const - return rclass.rtype_new_instance(hop.rtyper, klass, hop.llops) - def rtype_we_are_translated(hop): return hop.inputconst(lltype.Bool, True) @@ -319,7 +274,6 @@ BUILTIN_TYPER[rarithmetic.intmask] = rtype_intmask BUILTIN_TYPER[rarithmetic.r_uint] = rtype_r_uint BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict -BUILTIN_TYPER[objectmodel.instantiate] = rtype_instantiate BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated BUILTIN_TYPER[objectmodel.hlinvoke] = rtype_hlinvoke Modified: pypy/branch/hl-backend/pypy/rpython/rclass.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rclass.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rclass.py Thu Oct 13 16:47:44 2005 @@ -4,61 +4,7 @@ from pypy.annotation import model as annmodel from pypy.annotation.classdef import isclassdef from pypy.objspace.flow.model import Constant -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 -from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo, typeOf -from pypy.rpython.lltype import Array, Char, Void, attachRuntimeTypeInfo -from pypy.rpython.lltype import FuncType, Bool, Signed - -# -# There is one "vtable" per user class, with the following structure: -# A root class "object" has: -# -# struct object_vtable { -# struct object_vtable* parenttypeptr; -# RuntimeTypeInfo * rtti; -# Signed subclassrange_min; //this is also the id of the class itself -# Signed subclassrange_max; -# array { char } * name; -# struct object * instantiate(); -# } -# -# Every other class X, with parent Y, has the structure: -# -# struct vtable_X { -# struct vtable_Y super; // inlined -# ... // extra class attributes -# } - -# The type of the instances is: -# -# struct object { // for the root class -# struct object_vtable* typeptr; -# } -# -# struct X { -# struct Y super; // inlined -# ... // extra instance attributes -# } -# -# there's also a nongcobject - -OBJECT_VTABLE = ForwardReference() -TYPEPTR = Ptr(OBJECT_VTABLE) -OBJECT = GcStruct('object', ('typeptr', TYPEPTR)) -OBJECTPTR = Ptr(OBJECT) -OBJECT_VTABLE.become(Struct('object_vtable', - ('parenttypeptr', TYPEPTR), - ('subclassrange_min', Signed), - ('subclassrange_max', Signed), - ('rtti', Ptr(RuntimeTypeInfo)), - ('name', Ptr(Array(Char))), - ('instantiate', Ptr(FuncType([], OBJECTPTR))))) -# non-gc case -NONGCOBJECT = Struct('nongcobject', ('typeptr', TYPEPTR)) -NONGCOBJECTPTR = Ptr(OBJECT) +from pypy.rpython.rmodel import Repr, TyperError, needsgc def getclassrepr(rtyper, classdef): try: @@ -74,7 +20,7 @@ "have any attribute attached to it") result = getclassrepr(rtyper, None) else: - result = ClassRepr(rtyper, classdef) + result = rtyper.type_system.rclass.ClassRepr(rtyper, classdef) rtyper.class_reprs[classdef] = result rtyper.add_pendingsetup(result) return result @@ -88,7 +34,9 @@ # see getclassrepr() result = getinstancerepr(rtyper, None, nogc=False) else: - result = InstanceRepr(rtyper,classdef, does_need_gc=does_need_gc) + result = rtyper.type_system.rclass.InstanceRepr( + rtyper, classdef, does_need_gc=does_need_gc) + rtyper.instance_reprs[classdef, does_need_gc] = result rtyper.add_pendingsetup(result) return result @@ -96,23 +44,13 @@ class MissingRTypeAttribute(TyperError): pass - -def cast_vtable_to_typeptr(vtable): - while typeOf(vtable).TO != OBJECT_VTABLE: - vtable = vtable.super - return vtable - - -class ClassRepr(Repr): +class AbstractClassRepr(Repr): def __init__(self, rtyper, classdef): self.rtyper = rtyper self.classdef = classdef - if classdef is None: - # 'object' root type - self.vtable_type = OBJECT_VTABLE - else: - self.vtable_type = ForwardReference() - self.lowleveltype = Ptr(self.vtable_type) + + def _setup_repr(self): + pass def __repr__(self): if self.classdef is None: @@ -128,79 +66,6 @@ cls = self.classdef.cls return 'ClassR %s.%s' % (cls.__module__, cls.__name__) - def _setup_repr(self): - # NOTE: don't store mutable objects like the dicts below on 'self' - # before they are fully built, to avoid strange bugs in case - # of recursion where other code would uses these - # partially-initialized dicts. - clsfields = {} - pbcfields = {} - allmethods = {} - if self.classdef is not None: - # class attributes - llfields = [] - attrs = self.classdef.attrs.items() - attrs.sort() - for name, attrdef in attrs: - if attrdef.readonly: - s_value = attrdef.s_value - s_value = self.prepare_method(name, s_value, allmethods) - r = self.rtyper.getrepr(s_value) - mangled_name = 'cls_' + name - clsfields[name] = mangled_name, r - llfields.append((mangled_name, r.lowleveltype)) - # attributes showing up in getattrs done on the class as a PBC - extra_access_sets = self.rtyper.class_pbc_attributes.get( - self.classdef, {}) - for access_set, counter in extra_access_sets.items(): - for attr, s_value in access_set.attrs.items(): - r = self.rtyper.getrepr(s_value) - mangled_name = 'pbc%d_%s' % (counter, attr) - pbcfields[access_set, attr] = mangled_name, r - llfields.append((mangled_name, r.lowleveltype)) - # - self.rbase = getclassrepr(self.rtyper, self.classdef.basedef) - self.rbase.setup() - vtable_type = Struct('%s_vtable' % self.classdef.cls.__name__, - ('super', self.rbase.vtable_type), - *llfields) - self.vtable_type.become(vtable_type) - allmethods.update(self.rbase.allmethods) - self.clsfields = clsfields - self.pbcfields = pbcfields - self.allmethods = allmethods - self.vtable = None - - def prepare_method(self, name, s_value, allmethods): - # special-casing for methods: - # - a class (read-only) attribute that would contain a PBC - # with {func: classdef...} is probably meant to be used as a - # method, but in corner cases it could be a constant object - # of type MethodType that just sits here in the class. But - # as MethodType has a custom __get__ too and we don't support - # it, it's a very bad idea anyway. - if isinstance(s_value, annmodel.SomePBC): - s_value = self.classdef.matching(s_value) - debound = {} - count = 0 - for x, classdef in s_value.prebuiltinstances.items(): - if isclassdef(classdef): - #if classdef.commonbase(self.classdef) != self.classdef: - # raise TyperError("methods from PBC set %r don't belong " - # "in %r" % (s_value.prebuiltinstances, - # self.classdef.cls)) - count += 1 - classdef = True - debound[x] = classdef - if count > 0: - if count != len(s_value.prebuiltinstances): - raise TyperError("mixing functions and methods " - "in PBC set %r" % ( - s_value.prebuiltinstances,)) - s_value = annmodel.SomePBC(debound) - allmethods[name] = True - return s_value - def convert_const(self, value): if not isinstance(value, (type, types.ClassType)): raise TyperError("not a class: %r" % (value,)) @@ -213,150 +78,11 @@ raise TyperError("not a subclass of %r: %r" % ( self.classdef.cls, value)) # - return getclassrepr(self.rtyper, subclassdef).getvtable() + return getclassrepr(self.rtyper, subclassdef).getruntime() def get_ll_eq_function(self): return None - def getvtable(self, cast_to_typeptr=True): - """Return a ptr to the vtable of this type.""" - if self.vtable is None: - self.vtable = malloc(self.vtable_type, immortal=True) - self.setup_vtable(self.vtable, self) - # - vtable = self.vtable - if cast_to_typeptr: - vtable = cast_vtable_to_typeptr(vtable) - return vtable - - def setup_vtable(self, vtable, rsubcls): - """Initialize the 'self' portion of the 'vtable' belonging to the - given subclass.""" - if self.classdef is None: - # initialize the 'parenttypeptr' and 'name' fields - if rsubcls.classdef is not None: - vtable.parenttypeptr = rsubcls.rbase.getvtable() - vtable.subclassrange_min = rsubcls.classdef.minid - vtable.subclassrange_max = rsubcls.classdef.maxid - else: #for the root class - vtable.subclassrange_min = 0 - vtable.subclassrange_max = sys.maxint - rinstance = getinstancerepr(self.rtyper, rsubcls.classdef) - rinstance.setup() - if rinstance.needsgc: # only gc-case - vtable.rtti = getRuntimeTypeInfo(rinstance.object_type) - if rsubcls.classdef is None: - name = 'object' - else: - name = rsubcls.classdef.cls.__name__ - vtable.name = malloc(Array(Char), len(name)+1, immortal=True) - for i in range(len(name)): - vtable.name[i] = name[i] - vtable.name[len(name)] = '\x00' - if hasattr(rsubcls.classdef, 'my_instantiate'): - fn = rsubcls.classdef.my_instantiate - vtable.instantiate = self.rtyper.getfunctionptr(fn) - #else: the classdef was created recently, so no instantiate() - # could reach it - else: - # setup class attributes: for each attribute name at the level - # of 'self', look up its value in the subclass rsubcls - def assign(mangled_name, value): - if isinstance(value, staticmethod): - value = value.__get__(42) # staticmethod => bare function - llvalue = r.convert_const(value) - setattr(vtable, mangled_name, llvalue) - - mro = list(rsubcls.classdef.getmro()) - for fldname in self.clsfields: - mangled_name, r = self.clsfields[fldname] - if r.lowleveltype is Void: - continue - for clsdef in mro: - if fldname in clsdef.cls.__dict__: - value = clsdef.cls.__dict__[fldname] - assign(mangled_name, value) - break - # extra PBC attributes - for (access_set, attr), (mangled_name, r) in self.pbcfields.items(): - if r.lowleveltype is Void: - continue - for clsdef in mro: - try: - thisattrvalue = access_set.values[clsdef.cls, attr] - except KeyError: - if attr not in clsdef.cls.__dict__: - continue - thisattrvalue = clsdef.cls.__dict__[attr] - assign(mangled_name, thisattrvalue) - break - - # then initialize the 'super' portion of the vtable - self.rbase.setup_vtable(vtable.super, rsubcls) - - #def fromparentpart(self, v_vtableptr, llops): - # """Return the vtable pointer cast from the parent vtable's type - # to self's vtable type.""" - - def fromtypeptr(self, vcls, llops): - """Return the type pointer cast to self's vtable type.""" - castable(self.lowleveltype, vcls.concretetype) # sanity check - return llops.genop('cast_pointer', [vcls], - resulttype=self.lowleveltype) - - def getclsfieldrepr(self, attr): - """Return the repr used for the given attribute.""" - if attr in self.clsfields: - mangled_name, r = self.clsfields[attr] - return r - else: - if self.classdef is None: - raise MissingRTypeAttribute(attr) - return self.rbase.getfieldrepr(attr) - - def getclsfield(self, vcls, attr, llops): - """Read the given attribute of 'vcls'.""" - if attr in self.clsfields: - mangled_name, r = self.clsfields[attr] - v_vtable = self.fromtypeptr(vcls, llops) - cname = inputconst(Void, mangled_name) - return llops.genop('getfield', [v_vtable, cname], resulttype=r) - else: - if self.classdef is None: - raise MissingRTypeAttribute(attr) - return self.rbase.getclsfield(vcls, attr, llops) - - def setclsfield(self, vcls, attr, vvalue, llops): - """Write the given attribute of 'vcls'.""" - if attr in self.clsfields: - mangled_name, r = self.clsfields[attr] - v_vtable = self.fromtypeptr(vcls, llops) - cname = inputconst(Void, mangled_name) - llops.genop('setfield', [v_vtable, cname, vvalue]) - else: - if self.classdef is None: - raise MissingRTypeAttribute(attr) - self.rbase.setclsfield(vcls, attr, vvalue, llops) - - def getpbcfield(self, vcls, access_set, attr, llops): - if (access_set, attr) not in self.pbcfields: - raise TyperError("internal error: missing PBC field") - mangled_name, r = self.pbcfields[access_set, attr] - v_vtable = self.fromtypeptr(vcls, llops) - cname = inputconst(Void, mangled_name) - return llops.genop('getfield', [v_vtable, cname], resulttype=r) - - def rtype_issubtype(self, hop): - class_repr = get_type_repr(self.rtyper) - v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr) - if isinstance(v_cls2, Constant): - minid = hop.inputconst(Signed, v_cls2.value.subclassrange_min) - maxid = hop.inputconst(Signed, v_cls2.value.subclassrange_max) - return hop.gendirectcall(ll_issubclass_const, v_cls1, minid, maxid) - else: - v_cls1, v_cls2 = hop.inputargs(class_repr, class_repr) - return hop.gendirectcall(ll_issubclass, v_cls1, v_cls2) - def get_type_repr(rtyper): return getclassrepr(rtyper, None) @@ -370,24 +96,13 @@ return self.__class__, self.classdef -class InstanceRepr(Repr): - def __init__(self, rtyper, classdef, does_need_gc=True): +class AbstractInstanceRepr(Repr): + def __init__(self, rtyper, classdef): self.rtyper = rtyper self.classdef = classdef - if classdef is None: - if does_need_gc: - self.object_type = OBJECT - else: - self.object_type = NONGCOBJECT - else: - 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 _setup_repr(self): + pass def __repr__(self): if self.classdef is None: @@ -403,308 +118,29 @@ cls = self.classdef.cls return 'InstanceR %s.%s' % (cls.__module__, cls.__name__) - def _setup_repr(self): - # NOTE: don't store mutable objects like the dicts below on 'self' - # before they are fully built, to avoid strange bugs in case - # of recursion where other code would uses these - # partially-initialized dicts. - self.rclass = getclassrepr(self.rtyper, self.classdef) - fields = {} - allinstancefields = {} - if self.classdef is None: - fields['__class__'] = 'typeptr', get_type_repr(self.rtyper) - else: - # instance attributes - llfields = [] - attrs = self.classdef.attrs.items() - attrs.sort() - for name, attrdef in attrs: - if not attrdef.readonly: - r = self.rtyper.getrepr(attrdef.s_value) - mangled_name = 'inst_' + name - 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, not self.needsgc) - self.rbase.setup() - 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) - allinstancefields.update(self.rbase.allinstancefields) - allinstancefields.update(fields) - self.fields = fields - self.allinstancefields = allinstancefields - if self.needsgc: # only gc-case - attachRuntimeTypeInfo(self.object_type) - def _setup_repr_final(self): - 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: - return nullptr(self.object_type) - try: - classdef = self.rtyper.annotator.getuserclasses()[value.__class__] - except KeyError: - raise TyperError("no classdef: %r" % (value.__class__,)) - if classdef != self.classdef: - # if the class does not match exactly, check that 'value' is an - # instance of a subclass and delegate to that InstanceRepr - if classdef is None: - raise TyperError("not implemented: object() instance") - if classdef.commonbase(self.classdef) != self.classdef: - raise TyperError("not an instance of %r: %r" % ( - self.classdef.cls, value)) - rinstance = getinstancerepr(self.rtyper, classdef) - result = rinstance.convert_const(value) - return cast_pointer(self.lowleveltype, result) - # common case - try: - return self.prebuiltinstances[id(value)][1] - except KeyError: - self.setup() - 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 - - def get_ll_eq_function(self): - return ll_inst_eq - - def get_ll_hash_function(self): - if self.classdef is None: - return None - if self.rtyper.needs_hash_support( self.classdef.cls): - try: - return self._ll_hash_function - except AttributeError: - INSPTR = self.lowleveltype - def _ll_hash_function(ins): - return ll_inst_hash(cast_pointer(INSPTR, ins)) - self._ll_hash_function = _ll_hash_function - return _ll_hash_function - else: - return self.rbase.get_ll_hash_function() - - def initialize_prebuilt_instance(self, value, classdef, result): - if self.classdef is not None: - # recursively build the parent part of the instance - self.rbase.initialize_prebuilt_instance(value, classdef, - result.super) - # then add instance attributes from this level - for name, (mangled_name, r) in self.fields.items(): - if r.lowleveltype is Void: - llattrvalue = None - elif name == '_hash_cache_': # hash() support - llattrvalue = hash(value) - else: - try: - attrvalue = getattr(value, name) - except AttributeError: - warning("prebuilt instance %r has no attribute %r" % ( - value, name)) - continue - llattrvalue = r.convert_const(attrvalue) - setattr(result, mangled_name, llattrvalue) - else: - # OBJECT part - rclass = getclassrepr(self.rtyper, classdef) - result.typeptr = rclass.getvtable() - - #def parentpart(self, vinst, llops): - # """Return the pointer 'vinst' cast to the parent type.""" - # cname = inputconst(Void, 'super') - # return llops.genop('getsubstruct', [vinst, cname], - # resulttype=self.rbase.lowleveltype) - - def getfieldrepr(self, attr): - """Return the repr used for the given attribute.""" - if attr in self.fields: - mangled_name, r = self.fields[attr] - return r - else: - if self.classdef is None: - raise MissingRTypeAttribute(attr) - return self.rbase.getfieldrepr(attr) - - def getfield(self, vinst, attr, llops, force_cast=False): - """Read the given attribute (or __class__ for the type) of 'vinst'.""" - if attr in self.fields: - mangled_name, r = self.fields[attr] - cname = inputconst(Void, mangled_name) - if force_cast: - vinst = llops.genop('cast_pointer', [vinst], resulttype=self) - return llops.genop('getfield', [vinst, cname], resulttype=r) - else: - if self.classdef is None: - raise MissingRTypeAttribute(attr) - return self.rbase.getfield(vinst, attr, llops, force_cast=True) - - def setfield(self, vinst, attr, vvalue, llops, force_cast=False): - """Write the given attribute (or __class__ for the type) of 'vinst'.""" - if attr in self.fields: - mangled_name, r = self.fields[attr] - cname = inputconst(Void, mangled_name) - if force_cast: - vinst = llops.genop('cast_pointer', [vinst], resulttype=self) - llops.genop('setfield', [vinst, cname, vvalue]) - else: - if self.classdef is None: - raise MissingRTypeAttribute(attr) - self.rbase.setfield(vinst, attr, vvalue, llops, force_cast=True) + pass def new_instance(self, llops): - """Build a new instance, without calling __init__.""" - mallocop = 'malloc' - ctype = inputconst(Void, 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 - if self.classdef is not None: - flds = self.allinstancefields.keys() - flds.sort() - mro = list(self.classdef.getmro()) - for fldname in flds: - if fldname == '__class__': - continue - mangled_name, r = self.allinstancefields[fldname] - if r.lowleveltype is Void: - continue - for clsdef in mro: - if fldname in clsdef.cls.__dict__: - value = clsdef.cls.__dict__[fldname] - cvalue = inputconst(r, value) - self.setfield(vptr, fldname, cvalue, llops) - break - return vptr + pass def rtype_type(self, hop): - 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) + pass 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) + pass def rtype_getattr(self, hop): - attr = hop.args_s[1].const - vinst, vattr = hop.inputargs(self, Void) - if attr in self.allinstancefields: - return self.getfield(vinst, attr, hop.llops) - elif attr in self.rclass.allmethods: - # special case for methods: represented as their 'self' only - # (see MethodsPBCRepr) - return hop.r_result.get_method_from_instance(self, vinst, - hop.llops) - else: - vcls = self.getfield(vinst, '__class__', hop.llops) - return self.rclass.getclsfield(vcls, attr, hop.llops) + pass def rtype_setattr(self, hop): - attr = hop.args_s[1].const - r_value = self.getfieldrepr(attr) - vinst, vattr, vvalue = hop.inputargs(self, Void, r_value) - self.setfield(vinst, attr, vvalue, hop.llops) + pass def rtype_is_true(self, hop): - vinst, = hop.inputargs(self) - return hop.genop('ptr_nonzero', [vinst], resulttype=Bool) + pass - def ll_str(self, i): # doesn't work for non-gc classes! - instance = cast_pointer(OBJECTPTR, i) - from pypy.rpython import rstr - nameLen = len(instance.typeptr.name) - nameString = malloc(rstr.STR, nameLen-1) - i = 0 - while i < nameLen - 1: - nameString.chars[i] = instance.typeptr.name[i] - i += 1 - return rstr.ll_strconcat(rstr.instance_str_prefix, - rstr.ll_strconcat(nameString, - rstr.instance_str_suffix)) - - -class __extend__(pairtype(InstanceRepr, InstanceRepr)): - def convert_from_to((r_ins1, r_ins2), v, llops): - # which is a subclass of which? - if r_ins1.classdef is None or r_ins2.classdef is None: - basedef = None - else: - basedef = r_ins1.classdef.commonbase(r_ins2.classdef) - if basedef == r_ins2.classdef: - # r_ins1 is an instance of the subclass: converting to parent - v = llops.genop('cast_pointer', [v], - resulttype = r_ins2.lowleveltype) - return v - elif basedef == r_ins1.classdef: - # r_ins2 is an instance of the subclass: potentially unsafe - # casting, but we do it anyway (e.g. the annotator produces - # such casts after a successful isinstance() check) - v = llops.genop('cast_pointer', [v], - resulttype = r_ins2.lowleveltype) - return v - else: - 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 - else: - basedef = r_ins1.classdef.commonbase(r_ins2.classdef) - 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_ - - def rtype_ne(rpair, hop): - 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 ll_str(self, i): + pass # ____________________________________________________________ @@ -719,52 +155,3 @@ except KeyError: raise TyperError("no classdef: %r" % (cls,)) return annmodel.SomeInstance(classdef) - -# ____________________________________________________________ -# -# 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 - -def ll_issubclass(subcls, cls): - return cls.subclassrange_min <= subcls.subclassrange_min < cls.subclassrange_max - -def ll_issubclass_const(subcls, minid, maxid): - return minid <= subcls.subclassrange_min < maxid - - -def ll_isinstance(obj, cls): # obj should be cast to OBJECT or NONGCOBJECT - if not obj: - return False - obj_cls = obj.typeptr - return ll_issubclass(obj_cls, cls) - -def ll_isinstance_const(obj, minid, maxid): - if not obj: - return False - return ll_issubclass_const(obj.typeptr, minid, maxid) - -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 - -def ll_inst_eq(ins1, ins2): - return ins1 == ins2 - -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/branch/hl-backend/pypy/rpython/rlist.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rlist.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rlist.py Thu Oct 13 16:47:44 2005 @@ -6,7 +6,6 @@ from pypy.rpython.rslice import SliceRepr from pypy.rpython.rslice import startstop_slice_repr, startonly_slice_repr from pypy.rpython.rslice import minusone_slice_repr -from pypy.rpython.rclass import InstanceRepr from pypy.rpython.lltype import GcForwardReference, Ptr, GcArray, GcStruct from pypy.rpython.lltype import Void, Signed, malloc, typeOf, Primitive from pypy.rpython.lltype import Bool, nullptr Modified: pypy/branch/hl-backend/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rpbc.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rpbc.py Thu Oct 13 16:47:44 2005 @@ -684,7 +684,7 @@ class_repr = self.get_class_repr() return class_repr.getpbcfield(vcls, access_set, attr, llops) -class __extend__(pairtype(ClassesPBCRepr, rclass.ClassRepr)): +class __extend__(pairtype(ClassesPBCRepr, rclass.AbstractClassRepr)): def convert_from_to((r_clspbc, r_cls), v, llops): if r_cls.lowleveltype != r_clspbc.lowleveltype: return NotImplemented # good enough for now Modified: pypy/branch/hl-backend/pypy/rpython/rstr.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rstr.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rstr.py Thu Oct 13 16:47:44 2005 @@ -12,7 +12,6 @@ from pypy.rpython.rslice import minusone_slice_repr from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc from pypy.rpython.lltype import Bool, Void, GcArray, nullptr, typeOf, pyobjectptr -from pypy.rpython.rclass import InstanceRepr # ____________________________________________________________ @@ -334,6 +333,7 @@ argsiter = iter(sourcevarsrepr) + InstanceRepr = hop.rtyper.type_system.rclass.InstanceRepr for i, thing in enumerate(things): if isinstance(thing, tuple): code = thing[0] Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Thu Oct 13 16:47:44 2005 @@ -30,8 +30,6 @@ from pypy.rpython.rmodel import warning from pypy.rpython.normalizecalls import perform_normalizations from pypy.rpython.annlowlevel import annotate_lowlevel_helper -from pypy.rpython.exceptiondata import ExceptionData - from pypy.rpython.rmodel import log from pypy.rpython.typesystem import LowLevelTypeSystem,\ ObjectOrientedTypeSystem @@ -74,7 +72,13 @@ for s_primitive, lltype in annmodel.annotation_to_ll_map: r = self.getrepr(s_primitive) self.primitive_to_repr[r.lowleveltype] = r - self.exceptiondata = ExceptionData(self) + if type_system == "lltype": + from pypy.rpython.lltypesystem.exceptiondata import ExceptionData + + self.exceptiondata = ExceptionData(self) + else: + self.exceptiondata = None + try: self.seed = int(os.getenv('RTYPERSEED')) s = 'Using %d as seed for block shuffling' % self.seed Modified: pypy/branch/hl-backend/pypy/rpython/typesystem.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/typesystem.py (original) +++ pypy/branch/hl-backend/pypy/rpython/typesystem.py Thu Oct 13 16:47:44 2005 @@ -3,8 +3,8 @@ from pypy.annotation.pairtype import extendabletype -from pypy.rpython.ootype import ootype -from pypy.rpython import lltype # FIXME lltype in separate directory +from pypy.rpython.ootype import ootype # FIXME ootype dir to ootypesystem +from pypy.rpython.lltypesystem import lltype class TypeSystem(object): __metaclass__ = extendabletype @@ -35,6 +35,19 @@ class LowLevelTypeSystem(TypeSystem): callable_trait = (lltype.FuncType, lltype.functionptr) + def __getattr__(self, name): + """Lazy import to avoid circular dependencies.""" + if name == "rclass": + from pypy.rpython.lltypesystem import rclass + self.rclass = rclass + + return rclass + elif name == "BUILTIN_TYPER": + from pypy.rpython.lltypesystem import rbuiltin + self.BUILTIN_TYPER = rbuiltin.BUILTIN_TYPER + + return self.BUILTIN_TYPER + def deref(self, obj): assert isinstance(lltype.typeOf(obj), lltype.Ptr) return obj._obj @@ -45,6 +58,8 @@ class ObjectOrientedTypeSystem(TypeSystem): callable_trait = (ootype.StaticMethod, ootype.static_meth) + # FIXME rclass + def deref(self, obj): assert isinstance(ootype.typeOf(obj), ootype.OOType) return obj @@ -66,5 +81,3 @@ if hasattr(s_obj, "rtyper_makekey_ex"): return s_obj.rtyper_makekey_ex(rtyper) return s_obj.rtyper_makekey() - - From pedronis at codespeak.net Fri Oct 14 10:21:24 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 14 Oct 2005 10:21:24 +0200 (CEST) Subject: [pypy-svn] r18523 - in pypy/branch/hl-backend/pypy: annotation rpython rpython/ootype rpython/ootypesystem rpython/ootypesystem/test Message-ID: <20051014082124.A857B27B46@code1.codespeak.net> Author: pedronis Date: Fri Oct 14 10:21:15 2005 New Revision: 18523 Added: pypy/branch/hl-backend/pypy/rpython/ootypesystem/ - copied from r18522, pypy/branch/hl-backend/pypy/rpython/ootype/ Removed: pypy/branch/hl-backend/pypy/rpython/ootype/ Modified: pypy/branch/hl-backend/pypy/annotation/binaryop.py pypy/branch/hl-backend/pypy/annotation/builtin.py pypy/branch/hl-backend/pypy/annotation/model.py pypy/branch/hl-backend/pypy/annotation/unaryop.py pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooann.py pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ootype.py pypy/branch/hl-backend/pypy/rpython/rmodel.py pypy/branch/hl-backend/pypy/rpython/rtyper.py pypy/branch/hl-backend/pypy/rpython/typesystem.py Log: rename rpython/ootype package to ootypesystem Modified: pypy/branch/hl-backend/pypy/annotation/binaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/binaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/binaryop.py Fri Oct 14 10:21:15 2005 @@ -654,7 +654,7 @@ # annotation of low-level types from pypy.annotation.model import SomePtr, SomeOOInstance, SomeOOClass from pypy.annotation.model import ll_to_annotation, annotation_to_lltype -from pypy.rpython.ootype import ootype +from pypy.rpython.ootypesystem import ootype class __extend__(pairtype(SomePtr, SomePtr)): def union((p1, p2)): Modified: pypy/branch/hl-backend/pypy/annotation/builtin.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/builtin.py (original) +++ pypy/branch/hl-backend/pypy/annotation/builtin.py Fri Oct 14 10:21:15 2005 @@ -366,7 +366,7 @@ # ootype from pypy.annotation.model import SomeOOInstance, SomeOOClass -from pypy.rpython.ootype import ootype +from pypy.rpython.ootypesystem import ootype def new(I): assert I.is_constant() Modified: pypy/branch/hl-backend/pypy/annotation/model.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/model.py (original) +++ pypy/branch/hl-backend/pypy/annotation/model.py Fri Oct 14 10:21:15 2005 @@ -449,7 +449,7 @@ self.method = method from pypy.rpython import lltype -from pypy.rpython.ootype import ootype +from pypy.rpython.ootypesystem import ootype annotation_to_ll_map = [ (SomePBC({None: True}), lltype.Void), # also matches SomeImpossibleValue() Modified: pypy/branch/hl-backend/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/unaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/unaryop.py Fri Oct 14 10:21:15 2005 @@ -594,7 +594,7 @@ def is_true(p): return SomeBool() -from pypy.rpython.ootype import ootype +from pypy.rpython.ootypesystem import ootype class __extend__(SomeOOInstance): def getattr(r, s_attr): assert s_attr.is_constant(), "getattr on ref %r with non-constant field-name" % r.ootype Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooann.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooann.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooann.py Fri Oct 14 10:21:15 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.ootype.ootype import * +from pypy.rpython.ootypesystem.ootype import * from pypy.annotation import model as annmodel from pypy.objspace.flow import FlowObjSpace from pypy.translator.annrpython import RPythonAnnotator Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ooclean.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooclean.py Fri Oct 14 10:21:15 2005 @@ -1,6 +1,6 @@ from pypy.translator.translator import Translator from pypy.rpython import lltype -from pypy.rpython.ootype import ootype +from pypy.rpython.ootypesystem import ootype def specialize(f, input_types): t = Translator(f) Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootype/test/test_ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ootype.py Fri Oct 14 10:21:15 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.ootype.ootype import * +from pypy.rpython.ootypesystem.ootype import * import py def test_simple(): Modified: pypy/branch/hl-backend/pypy/rpython/rmodel.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rmodel.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rmodel.py Fri Oct 14 10:21:15 2005 @@ -4,7 +4,7 @@ from pypy.rpython.lltype import Void, Bool, Float, Signed, Char, UniChar from pypy.rpython.lltype import typeOf, LowLevelType, Ptr, PyObject from pypy.rpython.lltype import FuncType, functionptr, cast_ptr_to_int -from pypy.rpython.ootype import ootype +from pypy.rpython.ootypesystem import ootype from pypy.rpython.error import TyperError, MissingRTypeOperation # initialization states for Repr instances Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Fri Oct 14 10:21:15 2005 @@ -22,7 +22,7 @@ from pypy.rpython.lltype import LowLevelType, Ptr, ContainerType from pypy.rpython.lltype import FuncType, functionptr, typeOf, RuntimeTypeInfo from pypy.rpython.lltype import attachRuntimeTypeInfo, Primitive -from pypy.rpython.ootype import ootype +from pypy.rpython.ootypesystem import ootype from pypy.tool.sourcetools import func_with_new_name, valid_identifier from pypy.translator.unsimplify import insert_empty_block from pypy.rpython.rmodel import Repr, inputconst Modified: pypy/branch/hl-backend/pypy/rpython/typesystem.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/typesystem.py (original) +++ pypy/branch/hl-backend/pypy/rpython/typesystem.py Fri Oct 14 10:21:15 2005 @@ -3,7 +3,7 @@ from pypy.annotation.pairtype import extendabletype -from pypy.rpython.ootype import ootype # FIXME ootype dir to ootypesystem +from pypy.rpython.ootypesystem import ootype from pypy.rpython.lltypesystem import lltype class TypeSystem(object): From pedronis at codespeak.net Fri Oct 14 10:30:56 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 14 Oct 2005 10:30:56 +0200 (CEST) Subject: [pypy-svn] r18524 - pypy/extradoc/sprintinfo/paris Message-ID: <20051014083056.5FC2127B46@code1.codespeak.net> Author: pedronis Date: Fri Oct 14 10:30:54 2005 New Revision: 18524 Added: pypy/extradoc/sprintinfo/paris/ootype.txt (contents, props changed) Log: short description of what is going on with ootypes Added: pypy/extradoc/sprintinfo/paris/ootype.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris/ootype.txt Fri Oct 14 10:30:54 2005 @@ -0,0 +1,32 @@ +drafted a target type system for rtyping which has first-class support +for classes: ootype + +primitive types are the same as in lltype, + +to define a type of instance (a.k.a. class) we introduced + +Instance(name, , , ) + + = None|another Instance + is a dict mapping names to ootypes, or tuples (ootype, default-value) + +callable in ootype are either typed StaticMethod(arg-types, result-type) +or Meth(art-types-without-self, result-types) + +they have constructors: + +static_meth(STATICMETHOD, name, **attrs) +meth(METHOD, **attrs) + + is dict mapping names to meths + +there is a new(INSTANCE) operation to create new instances. + +We started a concrete implementation of this model running on CPython, +and adding annotation/rtyping support for the ootype itself. + +We also started refactoring the rtyper such that a parameter type_system +can be given to the constructor/Translator.specialize to choose +either "lltype" (the default) or the new "ootype". + + From tismer at codespeak.net Fri Oct 14 10:35:08 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 14 Oct 2005 10:35:08 +0200 (CEST) Subject: [pypy-svn] r18525 - in pypy/dist/pypy/translator/c: src test Message-ID: <20051014083508.D2ED227B48@code1.codespeak.net> Author: tismer Date: Fri Oct 14 10:35:06 2005 New Revision: 18525 Modified: pypy/dist/pypy/translator/c/src/address.h pypy/dist/pypy/translator/c/test/test_lladdresses.py Log: made addresses work on windows. Arithmetic with void pointers is not supported. Added comparison tests, too. Modified: pypy/dist/pypy/translator/c/src/address.h ============================================================================== --- pypy/dist/pypy/translator/c/src/address.h (original) +++ pypy/dist/pypy/translator/c/src/address.h Fri Oct 14 10:35:06 2005 @@ -5,9 +5,9 @@ /*** binary operations ***/ -#define OP_ADR_DELTA(x,y,r,err) r = ((x) - (y)) -#define OP_ADR_SUB(x,y,r,err) r = ((x) - (y)) -#define OP_ADR_ADD(x,y,r,err) r = ((x) + (y)) +#define OP_ADR_DELTA(x,y,r,err) r = ((char *)(x) - (char *)(y)) +#define OP_ADR_SUB(x,y,r,err) r = ((char *)(x) - (y)) +#define OP_ADR_ADD(x,y,r,err) r = ((char *)(x) + (y)) #define OP_ADR_EQ(x,y,r,err) r = ((x) == (y)) #define OP_ADR_NE(x,y,r,err) r = ((x) != (y)) Modified: pypy/dist/pypy/translator/c/test/test_lladdresses.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_lladdresses.py (original) +++ pypy/dist/pypy/translator/c/test/test_lladdresses.py Fri Oct 14 10:35:06 2005 @@ -71,4 +71,18 @@ res = fc() assert res - +def test_pointer_comparison(): + def f(): + result = 0 + for addr1 in [raw_malloc(1), NULL]: + addr2 = addr1 + 1 + result = result * 2 + int(addr1 == addr2) + result = result * 2 + int(addr1 != addr2) + result = result * 2 + int(addr1 < addr2) + result = result * 2 + int(addr1 <= addr2) + result = result * 2 + int(addr1 > addr2) + result = result * 2 + int(addr1 >= addr2) + return result + fc = compile(f, []) + res = fc() + assert res == int('011100' * 2, 2) From tismer at codespeak.net Fri Oct 14 10:36:29 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 14 Oct 2005 10:36:29 +0200 (CEST) Subject: [pypy-svn] r18526 - pypy/dist/pypy/translator/goal Message-ID: <20051014083629.609A327B46@code1.codespeak.net> Author: tismer Date: Fri Oct 14 10:36:27 2005 New Revision: 18526 Modified: pypy/dist/pypy/translator/goal/bench-windows.py pypy/dist/pypy/translator/goal/targetrpystonedalone.py Log: extended the windows benchmark to also include results from targetrpystonedalone, which are misleading but impressive. Modified: pypy/dist/pypy/translator/goal/bench-windows.py ============================================================================== --- pypy/dist/pypy/translator/goal/bench-windows.py (original) +++ pypy/dist/pypy/translator/goal/bench-windows.py Fri Oct 14 10:36:27 2005 @@ -78,7 +78,7 @@ CREATIONFLAGS = win32con.HIGH_PRIORITY_CLASS print "configured to run under high priority" -BENCH_EXECONFIG = 'bench_windows_exe.txt' +BENCH_EXECONFIG = '_bench_windows_exe.txt' bench_exe = None def reference(progname): @@ -103,16 +103,22 @@ size += os.path.getsize(win32api.GetModuleFileName(int(dll))) return ver, size -def run_pystone(executable=reference('python'), n=0): - argstr = PYSTONE_CMD % (str(n) and n or '') - txt = run_cmd('%s -c "%s"' % (executable, argstr)) +def run_pystone(executable=reference('python'), n=0, rpy=False): + if rpy: + txt = run_cmd('%s pystone' % executable) + else: + argstr = PYSTONE_CMD % (str(n) and n or '') + txt = run_cmd('%s -c "%s"' % (executable, argstr)) res = get_result(txt, PYSTONE_PATTERN) print res return res -def run_richards(executable=reference('python'), n=20): - argstr = RICHARDS_CMD % n - txt = run_cmd('%s -c "%s"' % (executable, argstr)) +def run_richards(executable=reference('python'), n=20, rpy=False): + if rpy: + txt = run_cmd('%s richards' % executable) + else: + argstr = RICHARDS_CMD % n + txt = run_cmd('%s -c "%s"' % (executable, argstr)) res = get_result(txt, RICHARDS_PATTERN) print res return res @@ -122,7 +128,7 @@ exes.sort() return exes -STAT_FILE = 'bench_windows.dump' +STAT_FILE = '_bench_windows.dump' def load_stats(statfile=STAT_FILE): try: dic = pickle.load(file(statfile, 'rb')) @@ -134,9 +140,11 @@ pickle.dump(dic, file(statfile, 'wb')) HEADLINE = '''\ -executable richards pystone size (MB)''' +executable richards pystone size (MB)''' FMT = '''\ -%-27s''' + '%5d %5.1fx %7.1f %5.1fx %5.2f' +%-27s''' + '%5d %5.1fx' + ' %9.1f %5.1fx %5.3f' +FMT2 = '''\ +%-27s''' + '%5.3f %5.1f/' + ' %9.1f %5.1f/ %5.3f' def main(): print 'getting the richards reference' @@ -149,25 +157,30 @@ exename = os.path.splitext(exe)[0] mtime = os.path.getmtime(exe) size = os.path.getsize(exe) + rpy = size < 500000 key = md5.new(file(exe,'rb').read()).digest() if key in prior: print 'skipped', exename resdic[key] = prior[key][:2] + (exename, mtime, size) else: - resdic[key] = (run_richards(exe, 2), run_pystone(exe, 20000), + resdic[key] = (run_richards(exe, 2,rpy), run_pystone(exe, 20000, rpy), exename, mtime, size) prior[key] = resdic[key] # save result, temporarily save_stats(prior) save_stats(resdic) # save cleaned result - res = [ (mtime, exe, size, rich, stone) + res = [ (stone / rich, exe, size, rich, stone) for rich, stone, exe, mtime, size in resdic.values()] version, size = run_version_size() - res.append( (9e9, 'python %s' % version, size, ref_rich, ref_stone) ) + res.append( (1.0, 'python %s' % version, size, ref_rich, ref_stone) ) res.sort() print HEADLINE - for mtime, exe, size, rich, stone in res: - print FMT % (exe, rich, rich / ref_rich, stone, ref_stone / stone, - size / float(1024 * 1024)) + for speed2, exe, size, rich, stone in res: + if speed2 <= 1.0: + print FMT % (exe, rich, rich / ref_rich, stone, ref_stone / stone, + size / float(1024 * 1024)) + else: + print FMT2 % (exe, rich, ref_rich / rich, stone, stone / ref_stone, + size / float(1024 * 1024)) if __name__ == '__main__': main() Modified: pypy/dist/pypy/translator/goal/targetrpystonedalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrpystonedalone.py (original) +++ pypy/dist/pypy/translator/goal/targetrpystonedalone.py Fri Oct 14 10:36:27 2005 @@ -51,8 +51,8 @@ try: n = abs(int(s)) except ValueError: - os.write(2, '%s is neither a valid option (pystone, richards)' - ' nor an integer\n') + os.write(2, '"%s" is neither a valid option (pystone, richards)' + ' nor an integer\n' % s) return 1 if not n: n = default From tismer at codespeak.net Fri Oct 14 10:37:59 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 14 Oct 2005 10:37:59 +0200 (CEST) Subject: [pypy-svn] r18527 - pypy/dist/pypy/translator/c Message-ID: <20051014083759.355CC27B48@code1.codespeak.net> Author: tismer Date: Fri Oct 14 10:37:56 2005 New Revision: 18527 Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/stackless.py Log: made the generated code a bit more readable and easier to debug. There is now one instruction per line. Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Fri Oct 14 10:37:56 2005 @@ -234,7 +234,11 @@ lst.append(self.expr(op.result)) lst.append(err) line = '%s(%s);' % (macro, ', '.join(lst)) - yield line + if '\n' in line: + for subline in line.split('\n'): + yield subline + else: + yield line if line.find(err) >= 0: reachable_err = len(to_release) to_release.append(op.result) @@ -404,11 +408,11 @@ # skip assignment of 'void' return value r = self.expr(op.result) line = '%s = %s' % (r, line) - line = '%s %s' % (line, self.check_directcall_result(op, err)) + line = '%s\n%s' % (line, self.check_directcall_result(op, err)) return line def check_directcall_result(self, op, err): - return 'if (RPyExceptionOccurred()) FAIL(%s);' % err + return 'if (RPyExceptionOccurred())\n\tFAIL(%s);' % err # low-level operations def generic_get(self, op, sourceexpr): @@ -418,7 +422,7 @@ # need to adjust the refcount of the result only for PyObjects if T == PyObjPtr: result.append(self.pyobj_incref_expr(newvalue, T)) - result = '\t'.join(result) + result = '\n'.join(result) if T is Void: result = '/* %s */' % result return result @@ -429,7 +433,7 @@ # insert write barrier T = self.lltypemap(op.args[2]) self.gcpolicy.write_barrier(result, newvalue, T, targetexpr) - result = '\t'.join(result) + result = '\n'.join(result) if T is Void: result = '/* %s */' % result return result @@ -518,7 +522,7 @@ elength, cdecl(itemtypename, '')) result = self.gcpolicy.zero_malloc(TYPE, esize, eresult, err) - result += '\t%s->%s = %s;' % (eresult, lenfld, elength) + result += '\n%s->%s = %s;' % (eresult, lenfld, elength) return 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 Fri Oct 14 10:37:56 2005 @@ -107,10 +107,12 @@ if increfstmt: result.append(increfstmt) if decrefstmt: - result.insert(0, '{ %s = %s;' % ( + result.insert(0, '%s = %s;' % ( cdecl(self.db.gettype(T), 'prev'), targetexpr)) result.append(decrefstmt) + result[:] = ['\t%s' % line for line in result] + result[0] = '{' + result[0] result.append('}') def generic_dealloc(self, expr, T): @@ -348,7 +350,7 @@ is_varsize, err) if gcinfo and gcinfo.finalizer: - result += ('\tGC_REGISTER_FINALIZER(%s, %s, NULL, NULL, NULL);' + result += ('\nGC_REGISTER_FINALIZER(%s, %s, NULL, NULL, NULL);' % (eresult, gcinfo.finalizer)) return result Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Fri Oct 14 10:37:56 2005 @@ -243,12 +243,12 @@ # add the checks for the unwinding case just after the directcall # in the source - unwind_check = "if (slp_frame_stack_bottom) goto %s;" % (savelabel,) + unwind_check = "if (slp_frame_stack_bottom)\n\tgoto %s;" % (savelabel,) exception_check = (super(SlpFunctionCodeGenerator, self) .check_directcall_result(op, err)) - return '%s\n %s:\n\t%s' % (unwind_check, - resumelabel, - exception_check) + return '%s\n %s:\n%s' % (unwind_check, + resumelabel, + exception_check) def signature_type(T): From tismer at codespeak.net Fri Oct 14 10:39:03 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 14 Oct 2005 10:39:03 +0200 (CEST) Subject: [pypy-svn] r18528 - pypy/dist/pypy/translator/c Message-ID: <20051014083903.0079A27B48@code1.codespeak.net> Author: tismer Date: Fri Oct 14 10:39:01 2005 New Revision: 18528 Modified: pypy/dist/pypy/translator/c/genc.py Log: reworked the source file splitting criteria. Files are now limited by number of lines. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Fri Oct 14 10:39:01 2005 @@ -132,7 +132,7 @@ # ____________________________________________________________ -SPLIT_CRITERIA = 170 +SPLIT_CRITERIA = 32767 # support VC++ 6.0 (7.1 can do 65535) MARKER = '/*/*/' # provide an easy way to split after generating @@ -148,9 +148,7 @@ def set_strategy(self, path): all_nodes = list(self.database.globalcontainers()) - # split off non-function nodes - # win32 has a problem: compiles but infinite recursion etc. - # trytocicumvent this by placing all non-func nodes into one file. + # split off non-function nodes. We don't try to optimize these, yet. funcnodes = [] othernodes = [] for node in all_nodes: @@ -158,7 +156,8 @@ funcnodes.append(node) else: othernodes.append(node) - if len(funcnodes) >= SPLIT_CRITERIA: + # for now, only split for stand-alone programs. + if self.database.standalone: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes @@ -180,15 +179,26 @@ def getothernodes(self): return self.othernodes[:] - def splitfuncnodes(self): - # silly first split, just by node count - # XXX filter constant stuff off and put it elsewhere - nodes = self.funcnodes[:] - nchunks = len(nodes) // SPLIT_CRITERIA or 1 - chunksize = (len(nodes) + nchunks - 1) // nchunks - while nodes: - yield self.uniquecname('implement.c'), nodes[:chunksize] - del nodes[:chunksize] + def splitnodesimpl(self, basecname, nodes, nextra, nbetween): + # produce a sequence of nodes, grouped into files + # which have no more than SPLIT_CRITERIA lines + used = nextra + part = [] + for node in nodes: + impl = list(node.implementation()) + if not impl: + continue + cost = len(impl) + nbetween + if used + cost > SPLIT_CRITERIA and part: + # split if criteria met, unless we would produce nothing. + yield self.uniquecname(basecname), part + part = [] + used = nextra + part.append( (node, impl) ) + used += cost + # generate left pieces + if part: + yield self.uniquecname(basecname), part def gen_readable_parts_of_source(self, f): if self.one_source_file: @@ -266,26 +276,33 @@ print >> fc, '/***********************************************************/' fc.close() - name = self.uniquecname('nonfuncnodes.c') - print >> f, '/* %s */' % name - fc = self.makefile(name) - print >> fc, '/***********************************************************/' - print >> fc, '/*** Non-function Implementations ***/' - print >> fc - print >> fc, '#define PYPY_NOT_MAIN_FILE' - print >> fc, '#include "common_header.h"' - print >> fc, '#include "structdef.h"' - print >> fc, '#include "forwarddecl.h"' - print >> fc - print >> fc, '#include "src/g_include.h"' - print >> fc - print >> fc, MARKER - for node in self.getothernodes(): - render_nonempty(node.implementation()) - print >> fc, '/***********************************************************/' - fc.close() + nextralines = 11 + 1 + for name, nodesimpl in self.splitnodesimpl('nonfuncnodes.c', + self.othernodes, + nextralines, 1): + print >> f, '/* %s */' % name + fc = self.makefile(name) + print >> fc, '/***********************************************************/' + print >> fc, '/*** Non-function Implementations ***/' + print >> fc + print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#include "common_header.h"' + print >> fc, '#include "structdef.h"' + print >> fc, '#include "forwarddecl.h"' + print >> fc + print >> fc, '#include "src/g_include.h"' + print >> fc + print >> fc, MARKER + for node, impl in nodesimpl: + print >> fc, '\n'.join(impl) + print >> fc, MARKER + print >> fc, '/***********************************************************/' + fc.close() - for name, nodes in self.splitfuncnodes(): + nextralines = 8 + len(self.preimpl) + 4 + 1 + for name, nodesimpl in self.splitnodesimpl('implement.c', + self.funcnodes, + nextralines, 1): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' @@ -302,9 +319,9 @@ print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER - linecount = 12 + len(self.preimpl) - for node in nodes: - linecount += render_nonempty(node.implementation()) + for node, impl in nodesimpl: + print >> fc, '\n'.join(impl) + print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() print >> f From cfbolz at codespeak.net Fri Oct 14 11:33:05 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 14 Oct 2005 11:33:05 +0200 (CEST) Subject: [pypy-svn] r18530 - pypy/extradoc/sprintinfo Message-ID: <20051014093305.3E5E427B48@code1.codespeak.net> Author: cfbolz Date: Fri Oct 14 11:33:03 2005 New Revision: 18530 Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: work planning for today Modified: pypy/extradoc/sprintinfo/paris-2005-planning.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-planning.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-planning.txt Fri Oct 14 11:33:03 2005 @@ -14,9 +14,26 @@ from 1pm, so if somebody wants to work in the afternoon, he has to go to one of the small rooms) -pairing wednesday +pairing friday ======================= +Compiler issues: adrien, arre + +ootypes: boris, michael, bert, (arre), (armin), (samuele) + +LLinterpreter requirements + plan: carl, holger, (armin), (samuele) + +compliancy testing on compiled PyPy, getting py.test to run on compiled PyPy: + anders, {christian}, [armin] + +- (improve refcounting) + +implementing the socket module: amaury, valentino + +working on an RPython Numeric module: ludovic, andrew + +experiment with callgraph analysis to reorder source code: Christian + stackless/cps: (same group continues, "re-"pairing inside) christian, armin Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Fri Oct 14 11:33:03 2005 @@ -16,13 +16,13 @@ JIT related work ----------------- -- support addresses in the backends +- (DONE) support addresses in the backends - an ll interpreter written in RPython - Saving ll graphs plus a loader written in RPython - Start thinking/experimenting with JIT generation at translation time -- start a genasm back-end +- (DONE the starting) start a genasm back-end Threading/concurrency ---------------------- @@ -30,12 +30,12 @@ - release the GIL around system calls - understand and possibly fix where the overhead, when threads are enabled, comes from -- generating (single-threaded) stackless C code +- (DONE) generating (single-threaded) stackless C code Implementation/translation --------------------------- -- stack overflow detection (needed to be able to run many compliancy tests) +- (somewhat DONE) stack overflow detection (needed to be able to run many compliancy tests) - try more interp. level optimisations (dicts with string keys, more agressive use of fastcall*...) - compute correct max stack size in compiler (?) From ac at codespeak.net Fri Oct 14 11:58:06 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 14 Oct 2005 11:58:06 +0200 (CEST) Subject: [pypy-svn] r18532 - in pypy/branch/hl-backend/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051014095806.AD11F27B46@code1.codespeak.net> Author: ac Date: Fri Oct 14 11:58:06 2005 New Revision: 18532 Added: pypy/branch/hl-backend/pypy/rpython/ootypesystem/rootype.py (contents, props changed) pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_oortype.py (contents, props changed) Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py pypy/branch/hl-backend/pypy/rpython/rbuiltin.py pypy/branch/hl-backend/pypy/rpython/rtyper.py Log: Initial work on rtyping code using explicit ootype. Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py Fri Oct 14 11:58:06 2005 @@ -37,7 +37,10 @@ return new(self) def __repr__(self): - return '<%s %s>' % (self, self._name) + return '<%s>' % (self,) + + def __str__(self): + return '%s(%s)' % (self.__class__.__name__, self._name) def _add_fields(self, fields): for name, defn in fields.iteritems(): Added: pypy/branch/hl-backend/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- (empty file) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/rootype.py Fri Oct 14 11:58:06 2005 @@ -0,0 +1,21 @@ +from pypy.annotation import model as annmodel +from pypy.rpython.rmodel import Repr + +class __extend__(annmodel.SomeOOInstance): + def rtyper_makerepr(self, rtyper): + return OOInstanceRepr(self.ootype) + def rtyper_makekey(self): + return self.__class__, self.ootype + +class OOInstanceRepr(Repr): + def __init__(self, ootype): + self.lowleveltype = ootype + +class __extend__(annmodel.SomeOOClass): + pass + +class __extend__(annmodel.SomeOOBoundMeth): + pass + +class __extend__(annmodel.SomeOOStaticMeth): + pass Added: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_oortype.py ============================================================================== --- (empty file) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_oortype.py Fri Oct 14 11:58:06 2005 @@ -0,0 +1,25 @@ + +from pypy.rpython.ootypesystem.ootype import * +from pypy.annotation import model as annmodel +from pypy.objspace.flow import FlowObjSpace +from pypy.translator.translator import Translator + +def gengraph(f, *args): + t = Translator(f) + t.annotate(args) + #t.view() + t.specialize(type_system="ootype") + #t.view() + return t.flowgraphs[f] + +def test_simple_class(): + C = Instance("test", None, {'a': Signed}) + + def f(): + c = new(C) + return c + + g = gengraph(f) + rettype = g.getreturnvar().concretetype + assert rettype == C + Modified: pypy/branch/hl-backend/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rbuiltin.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rbuiltin.py Fri Oct 14 11:58:06 2005 @@ -11,6 +11,7 @@ from pypy.rpython.rbool import bool_repr from pypy.rpython.rdict import rtype_r_dict from pypy.tool import sourcetools +from pypy.rpython.ootypesystem import ootype class __extend__(annmodel.SomeBuiltin): def rtyper_makerepr(self, rtyper): @@ -263,6 +264,11 @@ return hop.genop('runtime_type_info', vlist, resulttype = rptr.PtrRepr(lltype.Ptr(lltype.RuntimeTypeInfo))) +def rtype_new(hop): + assert hop.args_s[0].is_constant() + vlist = hop.inputargs(lltype.Void) + return hop.genop('new', vlist, + resulttype = hop.r_result.lowleveltype) BUILTIN_TYPER[lltype.malloc] = rtype_malloc BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer @@ -277,6 +283,7 @@ BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated BUILTIN_TYPER[objectmodel.hlinvoke] = rtype_hlinvoke +BUILTIN_TYPER[ootype.new] = rtype_new from pypy.rpython import extfunctable Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Fri Oct 14 11:58:06 2005 @@ -149,8 +149,9 @@ self.already_seen = {} self.specialize_more_blocks() - self.exceptiondata.make_helpers(self) - self.specialize_more_blocks() # for the helpers just made + if self.exceptiondata is not None: + self.exceptiondata.make_helpers(self) + self.specialize_more_blocks() # for the helpers just made def specialize_more_blocks(self): while True: @@ -797,3 +798,4 @@ from pypy.rpython import rexternalobj from pypy.rpython import rptr from pypy.rpython import raddress # memory addresses +from pypy.rpython.ootypesystem import rootype From tismer at codespeak.net Fri Oct 14 11:59:30 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 14 Oct 2005 11:59:30 +0200 (CEST) Subject: [pypy-svn] r18533 - pypy/dist/pypy/translator/c Message-ID: <20051014095930.1800B27B48@code1.codespeak.net> Author: tismer Date: Fri Oct 14 11:59:28 2005 New Revision: 18533 Modified: pypy/dist/pypy/translator/c/genc.py Log: dropped support for VC++ 6.0, left as a comment for those who really want to use it (highly dis-recommended) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Fri Oct 14 11:59:28 2005 @@ -132,7 +132,8 @@ # ____________________________________________________________ -SPLIT_CRITERIA = 32767 # support VC++ 6.0 (7.1 can do 65535) +#SPLIT_CRITERIA = 32767 # enable to support VC++ 6.0 +SPLIT_CRITERIA = 65535 # support VC++ 7.2 MARKER = '/*/*/' # provide an easy way to split after generating From mwh at codespeak.net Fri Oct 14 12:13:57 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 14 Oct 2005 12:13:57 +0200 (CEST) Subject: [pypy-svn] r18534 - pypy/extradoc/sprintinfo/paris Message-ID: <20051014101357.E13E427B56@code1.codespeak.net> Author: mwh Date: Fri Oct 14 12:13:57 2005 New Revision: 18534 Added: pypy/extradoc/sprintinfo/paris/ppc32.txt (contents, props changed) Log: ppc32 status Added: pypy/extradoc/sprintinfo/paris/ppc32.txt ============================================================================== --- (empty file) +++ pypy/extradoc/sprintinfo/paris/ppc32.txt Fri Oct 14 12:13:57 2005 @@ -0,0 +1,21 @@ +The PPC32 backend currently supports more-or-less any function that +manipulates only integers and does not call other functions or use +exceptions. + +There are a bunch of things which could be done: + +The register allocator is currently exceedingly stupid. Writing another +one would be a good idea, but this is pretty much independent from anything +else in pypy. + +On a similar note support for floats shouldn't be too hard. Would require +support for float registers, etc. Again thoroughly independent. + +Local exceptions (i.e. ones that do not escape from the function, e.g. +overflow errors) would be an interesting thing to support. + +There is no support at all for PBCs, and this is a huge topic that is +a large part of what the LLInterpreter group is worrying about. + +There is probably not much point in doing any of these things at this +sprint. From cfbolz at codespeak.net Fri Oct 14 12:14:29 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 14 Oct 2005 12:14:29 +0200 (CEST) Subject: [pypy-svn] r18535 - pypy/dist/pypy/doc Message-ID: <20051014101429.33CDC27B54@code1.codespeak.net> Author: cfbolz Date: Fri Oct 14 12:14:27 2005 New Revision: 18535 Modified: pypy/dist/pypy/doc/news.txt Log: change news item to contain link to second sprint report Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Fri Oct 14 12:14:27 2005 @@ -18,12 +18,13 @@ `continuation-passing`_ style (stackless), making the translation process work for target languages with more powerful object systems and some tiny steps into the JIT_ direction. Michael and Carl have written -a `report about day one`_. *(10/11/2005)* +a `report about day one`_ and `one about day two and three`_. *(10/14/2005)* .. _`Logilabs offices in Paris`: http://codespeak.net/pypy/extradoc/sprintinfo/paris-2005-sprint.html .. _JIT: http://en.wikipedia.org/wiki/Just-in-time_compilation .. _`continuation-passing`: http://en.wikipedia.org/wiki/Continuation_passing_style .. _`report about day one`: http://codespeak.net/pipermail/pypy-dev/2005q4/002510.html +.. _`one about day two and three`: http://codespeak.net/pipermail/pypy-dev/2005q4/002512.html PyPy release 0.7.0 =================== From ludal at codespeak.net Fri Oct 14 13:41:25 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Fri, 14 Oct 2005 13:41:25 +0200 (CEST) Subject: [pypy-svn] r18536 - pypy/dist/pypy/module/Numeric Message-ID: <20051014114125.B858B27B49@code1.codespeak.net> Author: ludal Date: Fri Oct 14 13:41:23 2005 New Revision: 18536 Added: pypy/dist/pypy/module/Numeric/ pypy/dist/pypy/module/Numeric/__init__.py (contents, props changed) pypy/dist/pypy/module/Numeric/interp_numeric.py (contents, props changed) pypy/dist/pypy/module/Numeric/test_numeric.py (contents, props changed) Log: (ludal, aft) started implementing a Numeric.array type (Work in progress) Added: pypy/dist/pypy/module/Numeric/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/Numeric/__init__.py Fri Oct 14 13:41:23 2005 @@ -0,0 +1,24 @@ +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + """An RPython reimplementation of the Numeric module +""" + + appleveldefs = { + } + + interpleveldefs = { + 'Float' : "space.wrap('d')", + 'Int' : "space.wrap('l')", +# 'array' : 'interp_numeric.w_array', + 'zeros' : 'interp_numeric.w_zeros', + } + +## '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', Added: pypy/dist/pypy/module/Numeric/interp_numeric.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/Numeric/interp_numeric.py Fri Oct 14 13:41:23 2005 @@ -0,0 +1,111 @@ +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.error import OperationError +from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root + + + +def get_storage_size( dims ): + n = 1 + for d in dims: + n *= d + assert d>0 + return d + +class W_Array(Wrappable): + + def __init__(self, space, dims ): + self.space = space + assert isinstance(dims, list) + self.dims = dims + self.strides = [1] + self.base_object = None + self.base_offset = 0 # needed later for offseting into a shared storage + stride = 1 + for n in self.dims[:-1]: + stride *= n + self.strides.append( stride ) + self.strides.reverse() + + def descr___getitem__( self, space, w_index ): + if space.is_true(space.isinstance( w_index, space.w_int )): + idx = space.unwrap( w_index ) + assert isinstance( idx, int ) + return self.get_single_item( space, [ idx ] ) + raise NotImplementedError + + def descr___setitem__( self, space, w_index, w_value ): + if space.is_true(space.isinstance( w_index, space.w_int )): + idx = space.unwrap( w_index ) + assert isinstance( idx, int ) + return self.set_single_item( space, [ idx ], w_value ) + raise NotImplementedError + + + def fget_shape( space, self ): + return space.newtuple( [ self.space.wrap( i ) for i in self.dims ] ) + + def fset_shape( space, self, w_tuple ): + pass + + def get_array_offset( self, idx_tuple ): + if len(idx_tuple)>len(self.dims): + # TODO raise OperationError + raise RuntimeError + idx = 0 + for i in range(len(idx_tuple)): + idx += self.strides[i]*idx_tuple[i] + return idx + + +class W_Array_Float(W_Array): + + def __init__(self, space, dims, storage=None ): + W_Array.__init__(self, space, dims ) + storage_size = get_storage_size(dims) + self.storage = [] + if storage is not None: + assert isinstance(storage, list) + # TODO return proper exception here + assert len(storage)==storage_size + assert isinstance(storage[0], float) + self.storage = storage + else: + self.storage = [0.0]*storage_size + + def get_single_item( self, space, idx_tuple ): + if len(idx_tuple)!=len(self.dims): + # TODO raise OperationError or remove this and make it a pre-condition + raise RuntimeError + idx = self.get_array_offset( idx_tuple ) + return space.wrap( self.storage[idx] ) + + def set_single_item( self, space, idx_tuple, w_value ): + idx = self.get_array_offset( idx_tuple ) + value = space.float_w( w_value ) + self.storage[idx] = value + +descr___getitem__ = interp2app( W_Array.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) +descr___setitem__ = interp2app( W_Array.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) + +#get_shape = GetProperty( W_Array_Float. + +W_Array.typedef = TypeDef("W_Array", + shape = GetSetProperty( W_Array.fget_shape, cls=W_Array), + __getitem__ = descr___getitem__, + __setitem__ = descr___setitem__, + ) + +W_Array_Float.typedef = TypeDef("W_Array_Float", W_Array.typedef, + ) + +def w_zeros( space, w_dim_tuple, type_str ): + dims = [] + for w_int in space.unpackiterable(w_dim_tuple): + dims.append( space.unwrap( w_int ) ) + if type_str == 'd': + return space.wrap(W_Array_Float( space, dims )) + raise OperationError( space.w_ValueError, space.wrap('Unknown type code') ) + +w_zeros.unwrap_spec = [ ObjSpace, W_Root, str ] Added: pypy/dist/pypy/module/Numeric/test_numeric.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/Numeric/test_numeric.py Fri Oct 14 13:41:23 2005 @@ -0,0 +1,15 @@ + + +from Numeric import zeros, Float + +a = zeros( (3,2), Float ) + +print a.shape + +assert a.shape == (3,2) + +b = zeros( (8,), Float ) + +print b[1], b[2] +b[1] = 1. +print b[1], b[2] From afa at codespeak.net Fri Oct 14 15:13:32 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 14 Oct 2005 15:13:32 +0200 (CEST) Subject: [pypy-svn] r18537 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051014131332.AEECD27B53@code1.codespeak.net> Author: afa Date: Fri Oct 14 15:13:30 2005 New Revision: 18537 Added: pypy/dist/pypy/module/_socket/ (props changed) pypy/dist/pypy/module/_socket/__init__.py pypy/dist/pypy/module/_socket/app_socket.py pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/ (props changed) pypy/dist/pypy/module/_socket/test/test_socket2.py Log: (valentino, afa): start of the socket module lots of functions are still missing Added: pypy/dist/pypy/module/_socket/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/__init__.py Fri Oct 14 15:13:30 2005 @@ -0,0 +1,34 @@ +# Package initialisation +from pypy.interpreter.mixedmodule import MixedModule +import _socket +import sys + +class Module(MixedModule): + appleveldefs = { + 'error' : 'app_socket.error', + 'herror' : 'app_socket.herror', + 'gaierror' : 'app_socket.gaierror', + 'timeout' : 'app_socket.timeout', + } + + interpleveldefs = { + } + +for name in """ + gethostbyname gethostbyname_ex gethostbyaddr gethostname + getservbyname getservbyport getprotobyname + fromfd socketpair + ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop + getaddrinfo getnameinfo + getdefaulttimeout setdefaulttimeout + """.split(): + + if hasattr(_socket, name): + Module.interpleveldefs[name] = 'interp_socket.%s' % (name, ) + +for constant in dir(_socket): + value = getattr(_socket, constant) + if constant.isupper() and type(value) in (int, str): + Module.interpleveldefs[constant] = "space.wrap(%s)" % value + +Module.interpleveldefs['has_ipv6'] = "space.wrap(%s)" % _socket.has_ipv6 Added: pypy/dist/pypy/module/_socket/app_socket.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/app_socket.py Fri Oct 14 15:13:30 2005 @@ -0,0 +1,20 @@ +"""Implementation module for socket operations. + +See the socket module for documentation.""" + +class error(Exception): + pass + +class herror(error): + pass + +class gaierror(error): + pass + +class timeout(error): + pass + +class SocketType: + pass + +socket = SocketType Added: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/interp_socket.py Fri Oct 14 15:13:30 2005 @@ -0,0 +1,61 @@ + +import socket +from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + +def gethostname(space): + """gethostname() -> string + + Return the current host name. + """ + return space.wrap(socket.gethostname()) +gethostname.unwrap_spec = [ObjSpace] + +def gethostbyname(space, name): + """gethostbyname(host) -> address + + Return the IP address (a string of the form '255.255.255.255') for a host. + """ + return space.wrap(socket.gethostbyname(name)) +gethostbyname.unwrap_spec = [ObjSpace, str] + +def gethostbyname_ex(space, name): + """gethostbyname_ex(host) -> (name, aliaslist, addresslist) + + Return the true host name, a list of aliases, and a list of IP addresses, + for a host. The host argument is a string giving a host name or IP number. + """ + return space.wrap(socket.gethostbyname_ex(name)) +gethostbyname_ex.unwrap_spec = [ObjSpace, str] + +def gethostbyaddr(space, ip_num): + """gethostbyaddr(host) -> (name, aliaslist, addresslist) + + Return the true host name, a list of aliases, and a list of IP addresses, + for a host. The host argument is a string giving a host name or IP number. + """ + return space.wrap(socket.gethostbyaddr(ip_num)) +gethostbyaddr.unwrap_spec = [ObjSpace, str] + +def getservbyname(space, name, w_proto = NoneNotWrapped): + """getservbyname(servicename[, protocolname]) -> integer + + Return a port number from a service name and protocol name. + The optional protocol name, if given, should be 'tcp' or 'udp', + otherwise any protocol will match. + """ + if w_proto is None: + return space.wrap(socket.getservbyname(name)) + else: + return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) +getservbyname.unwrap_spec = [ObjSpace, str, W_Root] + +def getservbyport(space, port): + """getservbyport(port[, protocolname]) -> string + + Return the service name from a port number and protocol name. + The optional protocol name, if given, should be 'tcp' or 'udp', + otherwise any protocol will match. + """ + +# getservbyport getprotobyname Added: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Fri Oct 14 15:13:30 2005 @@ -0,0 +1,51 @@ +from pypy.objspace.std import StdObjSpace +from pypy.tool.udir import udir +import py +import socket, sys + +def setup_module(mod): + mod.space = StdObjSpace(usemodules=['_socket']) + mod.w_socket = space.appexec([], "(): import _socket as m; return m") + +def test_gethostname(): + host = space.appexec([w_socket], "(_socket): return _socket.gethostname()") + assert space.unwrap(host) == socket.gethostname() + +def test_gethostbyname(): + host = "localhost" + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyname(host)") + assert space.unwrap(ip) == socket.gethostbyname(host) + +def test_gethostbyname_ex(): + host = "localhost" + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyname_ex(host)") + assert isinstance(space.unwrap(ip), tuple) + assert space.unwrap(ip) == socket.gethostbyname_ex(host) + +def test_gethostbyaddr(): + host = "localhost" + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyaddr(host)") + assert space.unwrap(ip) == socket.gethostbyaddr(host) + host = "127.0.0.1" + ip = space.appexec([w_socket, space.wrap(host)], + "(_socket, host): return _socket.gethostbyaddr(host)") + assert space.unwrap(ip) == socket.gethostbyaddr(host) + +def test_getservbyname(): + name = "smtp" + # 2 args version + port = space.appexec([w_socket, space.wrap(name)], + "(_socket, name): return _socket.getservbyname(name, 'tcp')") + # 1 arg version + if sys.version_info < (2, 4): + py.test.skip("getservbyname second argument is not optional before python 2.4") + port = space.appexec([w_socket, space.wrap(name)], + "(_socket, name): return _socket.getservbyname(name)") + +def test_has_ipv6(): + res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") + assert space.unwrap(res) == socket.has_ipv6 + From arigo at codespeak.net Fri Oct 14 15:44:10 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 15:44:10 +0200 (CEST) Subject: [pypy-svn] r18544 - in pypy/dist/pypy/objspace/std: . test Message-ID: <20051014134410.008B027B53@code1.codespeak.net> Author: arigo Date: Fri Oct 14 15:44:07 2005 New Revision: 18544 Modified: pypy/dist/pypy/objspace/std/longobject.py pypy/dist/pypy/objspace/std/test/test_longobject.py Log: if n==-sys.maxint-1, then -n wraps around in the translated PyPy and produces an infinite loop in W_LongObject.fromint(). Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Fri Oct 14 15:44:07 2005 @@ -99,10 +99,10 @@ def fromint(space, intval): if intval < 0: sign = -1 - ival = -intval + ival = r_uint(-intval) elif intval > 0: sign = 1 - ival = intval + ival = r_uint(intval) else: return W_LongObject(space, [0], 0) # Count the number of Python digits. @@ -118,7 +118,7 @@ t = ival p = 0 while t: - v.digits[p] = t & MASK + v.digits[p] = intmask(t & MASK) t >>= SHIFT p += 1 return v 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 Fri Oct 14 15:44:07 2005 @@ -409,3 +409,9 @@ raises(ValueError, math.log, 0) raises(ValueError, math.log, -1) raises(ValueError, math.log, -2) + + def test_long(self): + import sys + n = -sys.maxint-1 + assert long(n) == n + assert str(long(n)) == str(n) From arigo at codespeak.net Fri Oct 14 16:01:34 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 16:01:34 +0200 (CEST) Subject: [pypy-svn] r18545 - in pypy/dist/pypy/rpython: . test Message-ID: <20051014140134.6400727B54@code1.codespeak.net> Author: arigo Date: Fri Oct 14 16:01:30 2005 New Revision: 18545 Modified: pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/rpython/test/test_rint.py Log: Bug in str(-sys.maxint-1). Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Fri Oct 14 16:01:30 2005 @@ -295,7 +295,9 @@ sign = 0 if i < 0: sign = 1 - i = -i + i = r_uint(-i) + else: + i = r_uint(i) if i == 0: len = 1 temp[0] = '0' Modified: pypy/dist/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rint.py (original) +++ pypy/dist/pypy/rpython/test/test_rint.py Fri Oct 14 16:01:30 2005 @@ -1,3 +1,4 @@ +import sys from pypy.translator.translator import Translator from pypy.rpython.rtyper import RPythonTyper from pypy.annotation import model as annmodel @@ -62,7 +63,10 @@ res = interpret(dummy, [-123]) assert ''.join(res.chars) == '-123' - + + res = interpret(dummy, [-sys.maxint-1]) + assert ''.join(res.chars) == str(-sys.maxint-1) + def test_hex_of_int(): def dummy(i): return hex(i) From afa at codespeak.net Fri Oct 14 16:12:48 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 14 Oct 2005 16:12:48 +0200 (CEST) Subject: [pypy-svn] r18546 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051014141248.81F8E27B58@code1.codespeak.net> Author: afa Date: Fri Oct 14 16:12:46 2005 New Revision: 18546 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: (valentino, afa): more functions on socket need to test socket.fromfd Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Fri Oct 14 16:12:46 2005 @@ -37,7 +37,7 @@ return space.wrap(socket.gethostbyaddr(ip_num)) gethostbyaddr.unwrap_spec = [ObjSpace, str] -def getservbyname(space, name, w_proto = NoneNotWrapped): +def getservbyname(space, name, w_proto=NoneNotWrapped): """getservbyname(servicename[, protocolname]) -> integer Return a port number from a service name and protocol name. @@ -50,12 +50,40 @@ return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) getservbyname.unwrap_spec = [ObjSpace, str, W_Root] -def getservbyport(space, port): +def getservbyport(space, port, w_proto=NoneNotWrapped): """getservbyport(port[, protocolname]) -> string Return the service name from a port number and protocol name. The optional protocol name, if given, should be 'tcp' or 'udp', otherwise any protocol will match. """ + if w_proto is None: + return space.wrap(socket.getservbyport(port)) + else: + return space.wrap(socket.getservbyport(port, space.str_w(w_proto))) +getservbyport.unwrap_spec = [ObjSpace, int, W_Root] + +def getprotobyname(space, name): + """getprotobyname(name) -> integer + + Return the protocol number for the named protocol. (Rarely used.) + """ + return space.wrap(socket.getprotobyname(name)) +getprotobyname.unwrap_spec = [ObjSpace, str] + +def fromfd(space, fd, family, type, w_proto=NoneNotWrapped): + """fromfd(fd, family, type[, proto]) -> socket object + + Create a socket object from the given file descriptor. + The remaining arguments are the same as for socket(). + """ + if proto is None: + return space.wrap(socket.fromfd(fd, family, type)) + else: + return space.wrap(socket.fromfd(fd, family, type, space.int_w(proto))) +fromfd.unwrap_spec = [ObjSpace, int, int, int, int] -# getservbyport getprotobyname +# fromfd socketpair +# ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop +# getaddrinfo getnameinfo +# getdefaulttimeout setdefaulttimeout Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Fri Oct 14 16:12:46 2005 @@ -39,11 +39,41 @@ # 2 args version port = space.appexec([w_socket, space.wrap(name)], "(_socket, name): return _socket.getservbyname(name, 'tcp')") + assert space.unwrap(port) == 25 # 1 arg version if sys.version_info < (2, 4): py.test.skip("getservbyname second argument is not optional before python 2.4") port = space.appexec([w_socket, space.wrap(name)], "(_socket, name): return _socket.getservbyname(name)") + assert space.unwrap(port) == 25 + +def test_getservbyport(): + if sys.version_info < (2, 4): + py.test.skip("getservbyport does not exist before python 2.4") + port = 25 + # 2 args version + name = space.appexec([w_socket, space.wrap(port)], + "(_socket, port): return _socket.getservbyport(port, 'tcp')") + assert space.unwrap(name) == "smtp" + name = space.appexec([w_socket, space.wrap(port)], + """(_socket, port): + try: + return _socket.getservbyport(port, 42) + except TypeError: + return 'OK' + """) + assert space.unwrap(name) == 'OK' + # 1 arg version + name = space.appexec([w_socket, space.wrap(port)], + "(_socket, port): return _socket.getservbyport(port)") + assert space.unwrap(name) == "smtp" + +def test_getprotobyname(): + name = "tcp" + num = space.appexec([w_socket, space.wrap(name)], + "(_socket, name): return _socket.getprotobyname(name)") + assert space.unwrap(num) == socket.IPPROTO_TCP + def test_has_ipv6(): res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") From adim at codespeak.net Fri Oct 14 16:20:13 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Fri, 14 Oct 2005 16:20:13 +0200 (CEST) Subject: [pypy-svn] r18547 - pypy/dist/pypy/interpreter/pyparser/test Message-ID: <20051014142013.76EA527B54@code1.codespeak.net> Author: adim Date: Fri Oct 14 16:20:11 2005 New Revision: 18547 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astcompiler.py Log: (arre, adim) test astcompiler against all CPython's stdlib 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 Oct 14 16:20:11 2005 @@ -715,10 +715,8 @@ 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' + source = file(filepath).read() + yield check_expression, source, 'exec' def test_eval_string(): 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 Oct 14 16:20:11 2005 @@ -204,6 +204,19 @@ source = file(filepath).read() yield check_compile, source, 'exec' +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 not basename.endswith('.py'): + continue + filepath = os.path.join(STDLIB_PATH, basename) + # size = os.stat(filepath)[6] + # filter on size + # if size <= 10000: + source = file(filepath).read() + yield check_compile, source, 'exec' + def test_libstuff(): for snippet_name in LIBSTUFF: filepath = os.path.join(os.path.dirname(__file__), '../../../lib', snippet_name) From arigo at codespeak.net Fri Oct 14 16:22:12 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 16:22:12 +0200 (CEST) Subject: [pypy-svn] r18548 - in pypy/dist/pypy/rpython: . test Message-ID: <20051014142212.891EC27B56@code1.codespeak.net> Author: arigo Date: Fri Oct 14 16:22:09 2005 New Revision: 18548 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/test/test_rlist.py Log: Check for MemoryErrors in malloc_varsize, for tests that allocate e.g. lists of impossibly large sizes Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Fri Oct 14 16:22:09 2005 @@ -324,7 +324,10 @@ result = self.op_direct_call(malloc, *args) return self.llinterpreter.gc.adjust_result_malloc(result, obj, size) else: - return self.llt.malloc(obj, size) + try: + return self.llt.malloc(obj, size) + except MemoryError, e: + self.make_llexception(e) def op_flavored_malloc(self, flavor, obj): assert isinstance(flavor, str) 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 Fri Oct 14 16:22:09 2005 @@ -1,3 +1,4 @@ +import sys from pypy.translator.translator import Translator from pypy.rpython.lltype import * from pypy.rpython.rtyper import RPythonTyper @@ -500,3 +501,14 @@ assert res == 2 res = interpret(fn, [6]) assert res == 100 + +def test_memoryerror(): + def fn(i): + lst = [0] * i + lst[i-1] = 5 + return lst[0] + res = interpret(fn, [1]) + assert res == 5 + res = interpret(fn, [2]) + assert res == 0 + interpret_raises(MemoryError, fn, [sys.maxint]) From boria at codespeak.net Fri Oct 14 16:27:14 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 16:27:14 +0200 (CEST) Subject: [pypy-svn] r18550 - in pypy/branch/hl-backend/pypy/rpython: . lltypesystem Message-ID: <20051014142714.89ED127B5A@code1.codespeak.net> Author: boria Date: Fri Oct 14 16:27:13 2005 New Revision: 18550 Added: pypy/branch/hl-backend/pypy/rpython/lltypesystem/rpbc.py - copied, changed from r18524, pypy/branch/hl-backend/pypy/rpython/rpbc.py Modified: pypy/branch/hl-backend/pypy/rpython/lltypesystem/rclass.py pypy/branch/hl-backend/pypy/rpython/rpbc.py pypy/branch/hl-backend/pypy/rpython/rtyper.py pypy/branch/hl-backend/pypy/rpython/typesystem.py Log: (mwh, boria) * Coarse-grained refactoring of rpbc.py into general and lltype-specific parts. * All tests under rpython/test/ pass. Modified: pypy/branch/hl-backend/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/branch/hl-backend/pypy/rpython/lltypesystem/rclass.py Fri Oct 14 16:27:13 2005 @@ -9,7 +9,8 @@ AbstractInstanceRepr,\ MissingRTypeAttribute,\ getclassrepr, getinstancerepr,\ - get_type_repr, rtype_new_instance + get_type_repr, rtype_new_instance,\ + instance_annotation_for_cls 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 Modified: pypy/branch/hl-backend/pypy/rpython/rpbc.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rpbc.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rpbc.py Fri Oct 14 16:27:13 2005 @@ -38,7 +38,7 @@ raise TyperError("%r appears to be a method bound to %r, " "but it is not a function" % ( x, classdef)) - choice = MethodsPBCRepr + choice = rtyper.type_system.rpbc.MethodsPBCRepr elif x is None: continue # skipped, a None is allowed implicitely anywhere @@ -47,7 +47,7 @@ # classes if x in userclasses: # user classes - choice = ClassesPBCRepr + choice = rtyper.type_system.rpbc.ClassesPBCRepr elif type(x) is type and x.__module__ in sys.builtin_module_names: # special case for built-in types, seen in faking choice = getPyObjRepr @@ -60,10 +60,10 @@ # other kind of callable if isinstance(x, types.FunctionType): # function - choice = FunctionsPBCRepr + choice = rtyper.type_system.rpbc.FunctionsPBCRepr elif isinstance(x, types.MethodType): # prebuilt bound method - choice = MethodOfFrozenPBCRepr + choice = rtyper.type_system.rpbc.MethodOfFrozenPBCRepr else: raise TyperError("don't know about callable %r" % (x,)) @@ -125,7 +125,7 @@ try: return rtyper.pbc_reprs[access] except KeyError: - result = MultipleFrozenPBCRepr(rtyper, access) + result = rtyper.type_system.rpbc.MultipleFrozenPBCRepr(rtyper, access) rtyper.pbc_reprs[access] = result rtyper.add_pendingsetup(result) return result @@ -152,19 +152,13 @@ none_frozen_pbc_repr = NoneFrozenPBCRepr(None) -def rtype_is_None(robj1, rnone2, hop, pos=0): - if not isinstance(robj1.lowleveltype, Ptr): - raise TyperError('is None of instance of the non-pointer: %r' % (robj1)) - v1 = hop.inputarg(robj1, pos) - return hop.genop('ptr_iszero', [v1], resulttype=Bool) - class __extend__(pairtype(Repr, NoneFrozenPBCRepr)): def convert_from_to((r_from, _), v, llops): return inputconst(Void, None) def rtype_is_((robj1, rnone2), hop): - return rtype_is_None(robj1, rnone2, hop) + return hop.rtyper.type_system.rpbc.rtype_is_None(robj1, rnone2, hop) class __extend__(pairtype(NoneFrozenPBCRepr, Repr)): @@ -172,7 +166,8 @@ return inputconst(r_to, None) def rtype_is_((rnone1, robj2), hop): - return rtype_is_None(robj2, rnone1, hop, pos=1) + return hop.rtyper.type_system.rpbc.rtype_is_None( + robj2, rnone1, hop, pos=1) class __extend__(pairtype(NoneFrozenPBCRepr, robject.PyObjRepr)): @@ -181,168 +176,6 @@ # ____________________________________________________________ -class MultiplePBCRepr(Repr): - """Base class for PBCReprs of multiple PBCs that can include None - (represented as a NULL pointer).""" - def rtype_is_true(self, hop): - if hop.s_result.is_constant(): - assert hop.s_result.const is True # custom __nonzero__ on PBCs? - return hop.inputconst(Bool, hop.s_result.const) - else: - # None is a nullptr, which is false; everything else is true. - vlist = hop.inputargs(self) - return hop.genop('ptr_nonzero', vlist, resulttype=Bool) - - -class MultipleFrozenPBCRepr(MultiplePBCRepr): - """Representation selected for multiple non-callable pre-built constants.""" - def __init__(self, rtyper, access_set): - self.rtyper = rtyper - self.access_set = access_set - self.pbc_type = ForwardReference() - self.lowleveltype = Ptr(self.pbc_type) - self.pbc_cache = {} - - def _setup_repr(self): - llfields = [] - llfieldmap = {} - if self.access_set is not None: - attrlist = self.access_set.attrs.keys() - attrlist.sort() - for attr in attrlist: - s_value = self.access_set.attrs[attr] - r_value = self.rtyper.getrepr(s_value) - mangled_name = 'pbc_' + attr - llfields.append((mangled_name, r_value.lowleveltype)) - llfieldmap[attr] = mangled_name, r_value - self.pbc_type.become(Struct('pbc', *llfields)) - self.llfieldmap = llfieldmap - - def convert_const(self, pbc): - if pbc is None: - return nullptr(self.pbc_type) - if isinstance(pbc, types.MethodType) and pbc.im_self is None: - value = pbc.im_func # unbound method -> bare function -## if pbc not in self.access_set.objects: -## raise TyperError("not found in PBC set: %r" % (pbc,)) - try: - return self.pbc_cache[pbc] - except KeyError: - self.setup() - 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 is Void: - continue - try: - thisattrvalue = self.access_set.values[(pbc, attr)] - except KeyError: - try: - thisattrvalue = getattr(pbc, attr) - except AttributeError: - warning("PBC %r has no attribute %r" % (pbc, attr)) - continue - llvalue = r_value.convert_const(thisattrvalue) - setattr(result, mangled_name, llvalue) - return result - - def rtype_getattr(self, hop): - attr = hop.args_s[1].const - vpbc, vattr = hop.inputargs(self, Void) - return self.getfield(vpbc, attr, hop.llops) - - def getfield(self, vpbc, attr, llops): - mangled_name, r_value = self.llfieldmap[attr] - cmangledname = inputconst(Void, mangled_name) - return llops.genop('getfield', [vpbc, cmangledname], - resulttype = r_value) - -class __extend__(pairtype(MultipleFrozenPBCRepr, MultipleFrozenPBCRepr)): - def convert_from_to((r_pbc1, r_pbc2), v, llops): - if r_pbc1.access_set == r_pbc2.access_set: - return v - return NotImplemented - -class __extend__(pairtype(SingleFrozenPBCRepr, MultipleFrozenPBCRepr)): - def convert_from_to((r_pbc1, r_pbc2), v, llops): - value = r_pbc1.value - access = get_access_set(r_pbc2.rtyper, value) - if access is r_pbc2.access_set: - return inputconst(r_pbc2, value) - return NotImplemented - -# ____________________________________________________________ - - -class MethodOfFrozenPBCRepr(Repr): - """Representation selected for a PBC of method object(s) of frozen PBCs. - It assumes that all methods are the same function bound to different PBCs. - The low-level representation can then be a pointer to that PBC.""" - - def __init__(self, rtyper, s_pbc): - self.rtyper = rtyper - self.function = s_pbc.prebuiltinstances.keys()[0].im_func - # a hack to force the underlying function to show up in call_families - # (generally not needed, as normalizecalls() should ensure this, - # but needed for bound methods that are ll helpers) - call_families = rtyper.annotator.getpbccallfamilies() - call_families.find((None, self.function)) - im_selves = {} - for pbc, not_a_classdef in s_pbc.prebuiltinstances.items(): - if pbc is None: - raise TyperError("unsupported: variable of type " - "method-of-frozen-PBC or None") - assert pbc.im_func is self.function - assert not isclassdef(not_a_classdef) - im_selves[pbc.im_self] = True - self.s_im_self = annmodel.SomePBC(im_selves) - self.r_im_self = rtyper.getrepr(self.s_im_self) - self.lowleveltype = self.r_im_self.lowleveltype - - def get_s_callable(self): - return annmodel.SomePBC({self.function: True}) - - def get_r_implfunc(self): - r_func = self.rtyper.getrepr(self.get_s_callable()) - return r_func, 1 - - def convert_const(self, method): - if getattr(method, 'im_func', None) is not self.function: - raise TyperError("not a method bound on %r: %r" % (self.function, - method)) - return self.r_im_self.convert_const(method.im_self) - - def rtype_simple_call(self, hop): - return self.redispatch_call(hop, call_args=False) - - def rtype_call_args(self, hop): - return self.redispatch_call(hop, call_args=True) - - def redispatch_call(self, hop, call_args): - s_function = annmodel.SomePBC({self.function: True}) - hop2 = hop.copy() - hop2.args_s[0] = self.s_im_self # make the 1st arg stand for 'im_self' - hop2.args_r[0] = self.r_im_self # (same lowleveltype as 'self') - if isinstance(hop2.args_v[0], Constant): - hop2.args_v[0] = hop.inputarg(self, 0) - if call_args: - hop2.swap_fst_snd_args() - _, s_shape = hop2.r_s_popfirstarg() # temporarely remove shape - adjust_shape(hop2, s_shape) - c = Constant(self.function) - hop2.v_s_insertfirstarg(c, s_function) # insert 'function' - # now hop2 looks like simple_call(function, self, args...) - return hop2.dispatch() - -def adjust_shape(hop2, s_shape): - new_shape = (s_shape.const[0]+1,) + s_shape.const[1:] - c_shape = Constant(new_shape) - s_shape = hop2.rtyper.annotator.bookkeeper.immutablevalue(new_shape) - hop2.v_s_insertfirstarg(c_shape, s_shape) # reinsert adjusted shape - -# ____________________________________________________________ - - def getsignature(rtyper, func): f = rtyper.getcallable(func) graph = rtyper.type_system_deref(f).graph @@ -361,114 +194,6 @@ return False return True - -class FunctionsPBCRepr(MultiplePBCRepr): - """Representation selected for a PBC of function(s).""" - - def __init__(self, rtyper, s_pbc): - self.rtyper = rtyper - self.s_pbc = s_pbc - self._function_signatures = None - if len(s_pbc.prebuiltinstances) == 1: - # a single function - self.lowleveltype = Void - else: - signatures = self.function_signatures().values() - sig0 = signatures[0] - for sig1 in signatures[1:]: - assert typeOf(sig0[0]) == typeOf(sig1[0]) # XXX not implemented - assert sig0[1:] == sig1[1:] # XXX not implemented - self.lowleveltype = typeOf(sig0[0]) - - def get_s_callable(self): - return self.s_pbc - - def get_r_implfunc(self): - return self, 0 - - def get_signature(self): - return self.function_signatures().itervalues().next() - - def get_args_ret_s(self): - f, _, _ = self.get_signature() - graph = self.rtyper.type_system_deref(f).graph - rtyper = self.rtyper - return [rtyper.binding(arg) for arg in graph.getargs()], rtyper.binding(graph.getreturnvar()) - - def function_signatures(self): - if self._function_signatures is None: - self._function_signatures = {} - for func in self.s_pbc.prebuiltinstances: - if func is not None: - self._function_signatures[func] = getsignature(self.rtyper, - func) - assert self._function_signatures - return self._function_signatures - - def convert_const(self, value): - if value is None: - return nullptr(self.lowleveltype.TO) - if isinstance(value, types.MethodType) and value.im_self is None: - value = value.im_func # unbound method -> bare function - if value not in self.function_signatures(): - raise TyperError("%r not in %r" % (value, - self.s_pbc.prebuiltinstances)) - f, rinputs, rresult = self.function_signatures()[value] - return f - - def rtype_simple_call(self, hop): - f, rinputs, rresult = self.function_signatures().itervalues().next() - - if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): - # should not have an argument count mismatch - assert len(rinputs) == hop.nb_args-1, "normalization bug" - vlist = hop.inputargs(self, *rinputs) - else: - # if not normalized, should be a call to a known function - # or to functions all with same signature - funcs = self.function_signatures().keys() - assert samesig(funcs), "normalization bug" - func = funcs[0] - vlist = [hop.inputarg(self, arg=0)] - vlist += callparse.callparse('simple_call', func, rinputs, hop) - - return self.call(hop, f, vlist, rresult) - - def call(self, hop, f, vlist, rresult): - if self.lowleveltype is 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) - - def rtype_call_args(self, hop): - f, rinputs, rresult = self.function_signatures().itervalues().next() - # the function arguments may have been normalized by normalizecalls() - # already - if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): - vlist = hop.inputargs(self, Void, *rinputs) - vlist = vlist[:1] + vlist[2:] - else: - # if not normalized, should be a call to a known function - # or to functions all with same signature - funcs = self.function_signatures().keys() - assert samesig(funcs), "normalization bug" - func = funcs[0] - vlist = [hop.inputarg(self, arg=0)] - vlist += callparse.callparse('call_args', func, rinputs, hop) - - return self.call(hop, f, vlist, rresult) - -class __extend__(pairtype(FunctionsPBCRepr, FunctionsPBCRepr)): - def convert_from_to((r_fpbc1, r_fpbc2), v, llops): - # this check makes sense because both source and dest repr are FunctionsPBCRepr - if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: - return v - if r_fpbc1.lowleveltype is Void: - return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) - return NotImplemented - # ____________________________________________________________ def commonbase(classdefs): @@ -483,234 +208,3 @@ for cdef1 in classdef.getmro(): for attrname in cdef1.attrs: yield cdef1, attrname - - -class MethodsPBCRepr(Repr): - """Representation selected for a PBC of the form {func: classdef...}. - It assumes that all the methods come from the same name in a base - classdef.""" - - def __init__(self, rtyper, s_pbc): - self.rtyper = rtyper - self.s_pbc = s_pbc - if None in s_pbc.prebuiltinstances: - raise TyperError("unsupported: variable of type " - "bound-method-object or None") - basedef = commonbase(s_pbc.prebuiltinstances.values()) - for classdef1, name in allattributenames(basedef): - # don't trust the func.func_names and see if this 'name' would be - # the one under which we can find all these methods - for func, classdef in s_pbc.prebuiltinstances.items(): - try: - if func != getattr(classdef.cls, name).im_func: - break - except AttributeError: - break - else: - # yes! - self.methodname = name - self.classdef = classdef1 # where the Attribute is defined - break - else: - raise TyperError("cannot find a unique name under which the " - "methods can be found: %r" % ( - s_pbc.prebuiltinstances,)) - # the low-level representation is just the bound 'self' argument. - self.s_im_self = annmodel.SomeInstance(self.classdef) - self.r_im_self = rclass.getinstancerepr(rtyper, self.classdef) - self.lowleveltype = self.r_im_self.lowleveltype - - def convert_const(self, method): - if getattr(method, 'im_func', None) is None: - raise TyperError("not a bound method: %r" % method) - return self.r_im_self.convert_const(method.im_self) - - def get_r_implfunc(self): - r_class = self.r_im_self.rclass - mangled_name, r_func = r_class.clsfields[self.methodname] - return r_func, 1 - - def get_s_callable(self): - return self.s_pbc - - def get_method_from_instance(self, r_inst, v_inst, llops): - # The 'self' might have to be cast to a parent class - # (as shown for example in test_rclass/test_method_both_A_and_B) - return llops.convertvar(v_inst, r_inst, self.r_im_self) - - def rtype_hardwired_simple_call(self, hop): - return self.redispatch_call(hop, call_args=False, hardwired=True) - - def rtype_hardwired_call_args(self, hop): - return self.redispatch_call(hop, call_args=True, hardwired=True) - - def rtype_simple_call(self, hop): - return self.redispatch_call(hop, call_args=False) - - def rtype_call_args(self, hop): - return self.redispatch_call(hop, call_args=True) - - def redispatch_call(self, hop, call_args, hardwired=False): - hop2 = hop.copy() - if hardwired: - hop2.swap_fst_snd_args() # bring the hardwired function constant in front - func = hop2.args_v[0].value - s_func = annmodel.SomePBC({func: True}) - hop2.r_s_popfirstarg() # info captured, discard it - v_func = Constant(func) - else: - r_class = self.r_im_self.rclass - mangled_name, r_func = r_class.clsfields[self.methodname] - assert isinstance(r_func, FunctionsPBCRepr) - s_func = r_func.s_pbc - v_im_self = hop.inputarg(self, arg=0) - v_cls = self.r_im_self.getfield(v_im_self, '__class__', hop.llops) - v_func = r_class.getclsfield(v_cls, self.methodname, hop.llops) - - hop2.args_s[0] = self.s_im_self # make the 1st arg stand for 'im_self' - hop2.args_r[0] = self.r_im_self # (same lowleveltype as 'self') - - opname = 'simple_call' - if call_args: - hop2.swap_fst_snd_args() - _, s_shape = hop2.r_s_popfirstarg() - adjust_shape(hop2, s_shape) - opname = 'call_args' - - hop2.v_s_insertfirstarg(v_func, s_func) # insert 'function' - # now hop2 looks like simple_call(function, self, args...) - return hop2.dispatch(opname=opname) - - -# ____________________________________________________________ - - -class ClassesPBCRepr(Repr): - """Representation selected for a PBC of class(es).""" - - def __init__(self, rtyper, s_pbc): - self.rtyper = rtyper - self.s_pbc = s_pbc - if None in s_pbc.prebuiltinstances: - raise TyperError("unsupported: variable of type " - "class-pointer or None") - if s_pbc.is_constant(): - self.lowleveltype = Void - else: - self.lowleveltype = rclass.TYPEPTR - self._access_set = None - self._class_repr = None - - def get_access_set(self): - if self._access_set is None: - access_sets = self.rtyper.annotator.getpbcaccesssets() - classes = self.s_pbc.prebuiltinstances.keys() - _, _, access = access_sets.find(classes[0]) - for obj in classes[1:]: - _, _, access1 = access_sets.find(obj) - assert access1 is access # XXX not implemented - commonbase = access.commonbase - self._class_repr = rclass.getclassrepr(self.rtyper, commonbase) - self._access_set = access - return self._access_set - - def get_class_repr(self): - self.get_access_set() - return self._class_repr - - def convert_const(self, cls): - if cls not in self.s_pbc.prebuiltinstances: - raise TyperError("%r not in %r" % (cls, self)) - if self.lowleveltype is Void: - return cls - return rclass.get_type_repr(self.rtyper).convert_const(cls) - - def rtype_simple_call(self, hop): - return self.redispatch_call(hop, call_args=False) - - def rtype_call_args(self, hop): - return self.redispatch_call(hop, call_args=True) - - def redispatch_call(self, hop, call_args): - if self.lowleveltype is not Void: - # instantiating a class from multiple possible classes - vcls = hop.inputarg(self, arg=0) - access_set = self.get_access_set() - vnewfn = self.get_class_repr().getpbcfield(vcls, access_set, - '__new__', hop.llops) - hop2 = hop.copy() - hop2.r_s_popfirstarg() # discard the class pointer argument - hop2.v_s_insertfirstarg(vnewfn, access_set.attrs['__new__']) - # now hop2 looks like simple_call(klass__new__, args...) - return hop2.dispatch() - - # instantiating a single class - klass = self.s_pbc.const - v_instance = rclass.rtype_new_instance(hop.rtyper, klass, hop.llops) - try: - initfunc = klass.__init__.im_func - except AttributeError: - assert hop.nb_args == 1, ("arguments passed to __init__, " - "but no __init__!") - else: - s_instance = rclass.instance_annotation_for_cls(self.rtyper, klass) - s_init = self.rtyper.annotator.bookkeeper.immutablevalue(initfunc) - hop2 = hop.copy() - hop2.r_s_popfirstarg() # discard the class pointer argument - if call_args: - _, s_shape = hop2.r_s_popfirstarg() # temporarely remove shape - hop2.v_s_insertfirstarg(v_instance, s_instance) # add 'instance' - adjust_shape(hop2, s_shape) - else: - hop2.v_s_insertfirstarg(v_instance, s_instance) # add 'instance' - c = Constant(initfunc) - hop2.v_s_insertfirstarg(c, s_init) # add 'initfunc' - hop2.s_result = annmodel.SomePBC({None: True}) - hop2.r_result = self.rtyper.getrepr(hop2.s_result) - # now hop2 looks like simple_call(initfunc, instance, args...) - hop2.dispatch() - return v_instance - - def rtype_getattr(self, hop): - if hop.s_result.is_constant(): - return hop.inputconst(hop.r_result, hop.s_result.const) - else: - attr = hop.args_s[1].const - vcls, vattr = hop.inputargs(self, Void) - return self.getfield(vcls, attr, hop.llops) - - def getfield(self, vcls, attr, llops): - access_set = self.get_access_set() - class_repr = self.get_class_repr() - return class_repr.getpbcfield(vcls, access_set, attr, llops) - -class __extend__(pairtype(ClassesPBCRepr, rclass.AbstractClassRepr)): - def convert_from_to((r_clspbc, r_cls), v, llops): - if r_cls.lowleveltype != r_clspbc.lowleveltype: - return NotImplemented # good enough for now - return v - -class __extend__(pairtype(ClassesPBCRepr, ClassesPBCRepr)): - def convert_from_to((r_clspbc1, r_clspbc2), v, llops): - # this check makes sense because both source and dest repr are ClassesPBCRepr - if r_clspbc1.lowleveltype == r_clspbc2.lowleveltype: - return v - if r_clspbc1.lowleveltype is Void: - return inputconst(r_clspbc2, r_clspbc1.s_pbc.const) - return NotImplemented - - - -# ____________________________________________________________ - -def rtype_call_memo(hop): - memo_table = hop.args_v[0].value - if memo_table.s_result.is_constant(): - return hop.inputconst(hop.r_result, memo_table.s_result.const) - fieldname = memo_table.fieldname - assert hop.nb_args == 2, "XXX" - - r_pbc = hop.args_r[1] - assert isinstance(r_pbc, (MultipleFrozenPBCRepr, ClassesPBCRepr)) - v_table, v_pbc = hop.inputargs(Void, r_pbc) - return r_pbc.getfield(v_pbc, fieldname, hop.llops) Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Fri Oct 14 16:27:13 2005 @@ -515,7 +515,7 @@ return rslice.rtype_newslice(hop) def translate_op_call_memo(self, hop): - return rpbc.rtype_call_memo(hop) + return self.type_system.rpbc.rtype_call_memo(hop) def translate_op_call_specialcase(self, hop): return rspecialcase.rtype_call_specialcase(hop) Modified: pypy/branch/hl-backend/pypy/rpython/typesystem.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/typesystem.py (original) +++ pypy/branch/hl-backend/pypy/rpython/typesystem.py Fri Oct 14 16:27:13 2005 @@ -37,11 +37,17 @@ def __getattr__(self, name): """Lazy import to avoid circular dependencies.""" + # FIXME refactor into TypeSystem if name == "rclass": from pypy.rpython.lltypesystem import rclass self.rclass = rclass return rclass + elif name == "rpbc": + from pypy.rpython.lltypesystem import rpbc + self.rpbc = rpbc + + return rpbc elif name == "BUILTIN_TYPER": from pypy.rpython.lltypesystem import rbuiltin self.BUILTIN_TYPER = rbuiltin.BUILTIN_TYPER From arigo at codespeak.net Fri Oct 14 16:35:58 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 16:35:58 +0200 (CEST) Subject: [pypy-svn] r18551 - pypy/dist/pypy/doc Message-ID: <20051014143558.0D53727B56@code1.codespeak.net> Author: arigo Date: Fri Oct 14 16:35:55 2005 New Revision: 18551 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Progress. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 14 16:35:55 2005 @@ -783,8 +783,8 @@ - *b*, *b'*, *b''*... are maps from *V* to *A*. We call *state* a pair *(b,E)*. We say that a state *(b',E')* is more -general than a state *(b,E)* if for all variables *v* we have *b'(v) >= -b(v)* and *E'* includes at least all relations of *E*. There is: +general than a state *(b,E)* if for all variables *v* we have ``b'(v) >= +b(v)`` and *E'* includes at least all relations of *E*. There is: - a most general state, with *bmax(v) = Top* for all *v* and *Emax* identifying all variables with each other; @@ -854,15 +854,15 @@ .. _merge_into: In the sequel, a lot of rules will be based on the following -``merge_into`` operator. Given two variables *x* and *y*, -``merge_into(x,y)`` modifies the state as follows:: +``merge_into`` operator. Given an annotation *a* and a variable *x*, +``merge_into(a,x)`` modifies the state as follows:: - merge_into(x,y): - if b(x)=List(v) and b(y)=List(w): + merge_into(a,x): + if a=List(v) and b(x)=List(w): b' = b - E' = E union (v~w) + E' = E union (v ~ w) else: - b' = b with (y -> b(x) \/ b(y)) + b' = b with (x -> a \/ b(x)) E' = E where ``\/`` is the union in the lattice *A*. @@ -875,7 +875,7 @@ y = phi(x) ---------------------------------------- - merge_into(x,y) + merge_into(b(x),y) The purpose of the equivalence relation *E* is to force two identified variables to keep the same binding. The rationale for this is explained @@ -884,13 +884,13 @@ (x~y) in E ---------------------------------------- - merge_into(x,y) - merge_into(y,x) + merge_into(b(x),y) + merge_into(b(y),x) -Note that in theory, all rules should be tried repeatedly until none of +Note that a priori, all rules should be tried repeatedly until none of them generalizes the state any more, at which point we have reached a -fixpoint. In practice, the rules are well suited to a simple metarule -that tracks a small set of rules that can possibly apply. Only these +fixpoint. However, the rules are well suited to a simple metarule that +tracks a small set of rules that can possibly apply. Only these "scheduled" rules are tried. The metarule is as follows: - when an identification *x~y* is added to *E*, then the rule @@ -966,7 +966,7 @@ setitem(x,y,z), b(x)=List(v) -------------------------------------------- - merge_into(z,v) + merge_into(b(z),v) Reading an item out a list requires care to ensure that the rule is rescheduled if the binding of the hidden variable is generalized. We do @@ -1119,7 +1119,7 @@ setattr(x,attr,z), b(x)=Inst(C) --------------------------------------------------------------------- E' = E union (v_C.attr ~ v_D.attr) for all D subclass of C - merge_into(z, v_C.attr) + merge_into(b(z), v_C.attr) Note the similarity with the ``getitem`` and ``setitem`` of lists, in particular the usage of the auxiliary variable *z'*. @@ -1166,23 +1166,23 @@ for each c in set: if c is a function: E' = E union (z ~ returnvar_c) - merge_into(y1, arg_c_1) + merge_into(b(y1), arg_c_1) ... - merge_into(yn, arg_c_n) + merge_into(b(yn), arg_c_n) if c is a class: let f = c.__init__ - b' = b with (z -> b(z) \/ Inst(c)) - and (arg_f_1 -> b(arg_f_1) \/ Inst(c)) - merge_into(y1, arg_f_2) + merge_into(Inst(c), z) + merge_into(Inst(c), arg_f_1) + merge_into(b(y1), arg_f_2) ... - merge_into(yn, arg_f_(n+1)) + merge_into(b(yn), arg_f_(n+1)) if c is a method: let class.f = c E' = E union (z ~ returnvar_f) - b' = b with (arg_f_1 -> b(arg_f_1) \/ Inst(class)) - merge_into(y1, arg_f_2) + merge_into(Inst(class), arg_f_1) + merge_into(b(y1), arg_f_2) ... - merge_into(yn, arg_f_(n+1)) + merge_into(b(yn), arg_f_(n+1)) Calling a class returns an instance and flows the annotations into the contructor ``__init__`` of the class. Calling a method inserts the @@ -1191,17 +1191,67 @@ method is found). +Termination and soundness +~~~~~~~~~~~~~~~~~~~~~~~~~ + +As the annotation process is a fix-point search, it is necessary for +completeness to prove more formally that it is well-behaved. The +following proofs are all rather easy given the approach we have taken. + Termination -~~~~~~~~~~~ +*********** + +We first have to check that each rule can only turn a state *(b,E)* into +a state *(b',E')* that is either identical or more general. To do so, +we first verify that they all have the following properties: + +* if *z* is the result variable of an operation, the binding ``b(z)`` is + only ever modified by the rule (or rules) about this operation: this + is true because *E* never identifies such a result variable with any + other variable. + +* the annotation ``b(z)`` of such a result variable can only become more + general: using the previous point, this can be checked on the rule (or + rules) of each operation independently. Indeed, there are only two + ways in which ``b(z)`` is modified: by ``merge_into(..., z)``, which + trivially guarantees the property by being based on the union operator + ``\/`` of the lattice, or explicitely in a way that can easily be + checked to respect the property. + +... + + +Each basic step (execution of one rule) can lead to the generalization +of the state. If it does, then other rules may be scheduled or +re-scheduled for execution. The state can only be generalized a finite +number of times because both the lattice *A* and the set of variables +*V* of which *E* is an equivalence relation are finite. If a rule does +not lead to any generalization, then it does not trigger re-scheduling +of any other rule. This ensures that the process eventually terminates. + +The extended lattice used in practice is a priori not finite. As we did +not describe this lattice formally here, we have to skip the (easy) +proof that it still contains no infinite ascending chain. An ascending +chain is a sequence where each item is strictly larger than the previous +one. + +Soundness +********* + +We define an annotation state to be *sound* if none of the rules would +lead to further Xxx. + XXX termination + soundness + most-precise-fixpoint-ness + complexity +Complexity +********** + The lattice is finite, although its size depends on the size of the program. The List part has the same size as *V*, and the Pbc part is exponential on the number of prebuilt constants. However, in this model -a chain of annotations (where each one is larger than the previous) -cannot be longer than:: +a chain of annotations cannot be longer than:: max(5, number-of-pbcs + 3, depth-of-class-hierarchy + 3). From arigo at codespeak.net Fri Oct 14 16:39:03 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 16:39:03 +0200 (CEST) Subject: [pypy-svn] r18552 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20051014143903.39AED27B56@code1.codespeak.net> Author: arigo Date: Fri Oct 14 16:38:59 2005 New Revision: 18552 Modified: pypy/dist/pypy/translator/c/funcgen.py pypy/dist/pypy/translator/c/src/mem.h pypy/dist/pypy/translator/c/test/test_annotated.py Log: Check for impossibly large number of items before malloc'ing arrays. Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Fri Oct 14 16:38:59 2005 @@ -517,11 +517,19 @@ eresult = self.expr(op.result) if VARPART.OF is Void: # strange esize = 'sizeof(%s)' % (cdecl(typename, ''),) + result = '' else: - esize = 'sizeof(%s)+((%s-1)*sizeof(%s))' % (cdecl(typename, ''), - elength, - cdecl(itemtypename, '')) - result = self.gcpolicy.zero_malloc(TYPE, esize, eresult, err) + itemtype = cdecl(itemtypename, '') + result = 'OP_MAX_VARSIZE(%s, %s, %s);\n' % ( + elength, + itemtype, + err) + esize = 'sizeof(%s)-sizeof(%s)+%s*sizeof(%s)' % ( + cdecl(typename, ''), + itemtype, + elength, + itemtype) + result += self.gcpolicy.zero_malloc(TYPE, esize, eresult, err) result += '\n%s->%s = %s;' % (eresult, lenfld, elength) return result 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 Fri Oct 14 16:38:59 2005 @@ -3,6 +3,17 @@ /*** C header subsection: operations on LowLevelTypes ***/ +/* a reasonably safe bound on the largest allowed argument value + that we can pass to malloc. This is used for var-sized mallocs + to compute the largest allowed number of items in the array. */ +#define MAXIMUM_MALLOCABLE_SIZE (LONG_MAX-4096) + +#define OP_MAX_VARSIZE(numitems, itemtype, err) { \ + if ((numitems) > (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype))) \ + FAIL_EXCEPTION(err, PyExc_MemoryError, "addr space overflow"); \ + } + + /* XXX hack to initialize the refcount of global structures: officially, we need a value equal to the number of references to this global from other globals, plus one. This upper bound "approximation" will do... */ Modified: pypy/dist/pypy/translator/c/test/test_annotated.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_annotated.py (original) +++ pypy/dist/pypy/translator/c/test/test_annotated.py Fri Oct 14 16:38:59 2005 @@ -1,5 +1,5 @@ import autopath -import py +import py, sys from pypy.translator.tool.cbuild import skip_missing_compiler from pypy.translator.translator import Translator @@ -166,3 +166,14 @@ fn = self.getcompiled(f) assert fn(-4.5) == 92.125 assert fn(4.5) == 90.125 + + def test_memoryerror(self): + def f(i=int): + lst = [0]*i + lst[-1] = 5 + return lst[0] + fn = self.getcompiled(f) + assert fn(1) == 5 + assert fn(2) == 0 + py.test.raises(MemoryError, fn, sys.maxint//2+1) + py.test.raises(MemoryError, fn, sys.maxint) From bert at codespeak.net Fri Oct 14 16:51:27 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Fri, 14 Oct 2005 16:51:27 +0200 (CEST) Subject: [pypy-svn] r18553 - in pypy/branch/hl-backend/pypy: annotation rpython/ootypesystem rpython/ootypesystem/test Message-ID: <20051014145127.9C12227B57@code1.codespeak.net> Author: bert Date: Fri Oct 14 16:51:27 2005 New Revision: 18553 Modified: pypy/branch/hl-backend/pypy/annotation/unaryop.py pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py pypy/branch/hl-backend/pypy/rpython/ootypesystem/rootype.py pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooann.py pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_oortype.py Log: added rtyper operations oogetfield, oosetfield, oosend (bert, arre, samuele) Modified: pypy/branch/hl-backend/pypy/annotation/unaryop.py ============================================================================== --- pypy/branch/hl-backend/pypy/annotation/unaryop.py (original) +++ pypy/branch/hl-backend/pypy/annotation/unaryop.py Fri Oct 14 16:51:27 2005 @@ -603,6 +603,12 @@ return SomeOOBoundMeth(r.ootype, s_attr.const) return ll_to_annotation(v) + def setattr(r, s_attr, s_value): + assert s_attr.is_constant(), "setattr on ref %r with non-constant field-name" % r.ootype + v = annotation_to_lltype(s_value) + setattr(r.ootype._example(), s_attr.const, + v._example()) + class __extend__(SomeOOBoundMeth): def simple_call(m, *args_s): llargs = [annotation_to_lltype(arg_s)._example() for arg_s in args_s] Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/ootype.py Fri Oct 14 16:51:27 2005 @@ -4,9 +4,9 @@ from pypy.tool.uid import Hashable from pypy.tool.tls import tlsobject from types import NoneType -from pypy.rpython.lltype import LowLevelType, Signed, Unsigned, Float, Char -from pypy.rpython.lltype import Bool, Void, UniChar, typeOf, Primitive -from pypy.rpython.lltype import frozendict +from pypy.rpython.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char +from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, Primitive +from pypy.rpython.lltypesystem.lltype import frozendict class OOType(LowLevelType): pass @@ -207,13 +207,9 @@ class _bound_meth(object): def __init__(self, inst, meth): - #self._TYPE = self self.inst = inst self.meth = meth - #def _example(self): - # return self - def __call__(self, *args): return self.meth._checkargs(args)(self.inst, *args) Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootypesystem/rootype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/rootype.py Fri Oct 14 16:51:27 2005 @@ -1,5 +1,7 @@ from pypy.annotation import model as annmodel from pypy.rpython.rmodel import Repr +from pypy.rpython.ootypesystem.ootype import Void +from pypy.annotation.pairtype import pairtype class __extend__(annmodel.SomeOOInstance): def rtyper_makerepr(self, rtyper): @@ -7,15 +9,47 @@ def rtyper_makekey(self): return self.__class__, self.ootype +class __extend__(annmodel.SomeOOBoundMeth): + def rtyper_makerepr(self, rtyper): + return OOBoundMethRepr(self.ootype, self.name) + def rtyper_makekey(self): + return self.__class__, self.ootype, self.name + class OOInstanceRepr(Repr): def __init__(self, ootype): self.lowleveltype = ootype -class __extend__(annmodel.SomeOOClass): - pass + def rtype_getattr(self, hop): + attr = hop.args_s[1].const + s_inst = hop.args_s[0] + meth = self.lowleveltype._lookup(attr) + if meth is not None: + # just return instance - will be handled by simple_call + return hop.inputarg(hop.r_result, arg=0) + self.lowleveltype._check_field(attr) + vlist = hop.inputargs(self, Void) + return hop.genop("oogetfield", vlist, + resulttype = hop.r_result.lowleveltype) -class __extend__(annmodel.SomeOOBoundMeth): - pass + def rtype_setattr(self, hop): + attr = hop.args_s[1].const + self.lowleveltype._check_field(attr) + vlist = hop.inputargs(self, Void, hop.args_r[2]) + return hop.genop('oosetfield', vlist) + +class OOBoundMethRepr(Repr): + def __init__(self, ootype, name): + self.lowleveltype = ootype + self.name = name + + def rtype_simple_call(self, hop): + vlist = hop.inputargs(self, *hop.args_r[1:]) + cname = hop.inputconst(Void, self.name) + return hop.genop("oosend", [cname]+vlist, + resulttype = hop.r_result.lowleveltype) + + +class __extend__(pairtype(OOInstanceRepr, OOBoundMethRepr)): -class __extend__(annmodel.SomeOOStaticMeth): - pass + def convert_from_to(_, v, llops): + return v Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooann.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooann.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooann.py Fri Oct 14 16:51:27 2005 @@ -9,6 +9,7 @@ def oof(): c = new(C) + c.a = 5 return c.a a = RPythonAnnotator() Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_oortype.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_oortype.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_oortype.py Fri Oct 14 16:51:27 2005 @@ -4,12 +4,14 @@ from pypy.objspace.flow import FlowObjSpace from pypy.translator.translator import Translator -def gengraph(f, *args): +def gengraph(f, args=[], viewBefore=False, viewAfter=False): t = Translator(f) t.annotate(args) - #t.view() + if viewBefore: + t.view() t.specialize(type_system="ootype") - #t.view() + if viewAfter: + t.view() return t.flowgraphs[f] def test_simple_class(): @@ -23,3 +25,30 @@ rettype = g.getreturnvar().concretetype assert rettype == C +def test_simple_field(): + C = Instance("test", None, {'a': (Signed, 3)}) + + def f(): + c = new(C) + c.a = 5 + return c.a + + g = gengraph(f) + rettype = g.getreturnvar().concretetype + assert rettype == Signed + +def test_simple_method(): + C = Instance("test", None, {'a': (Signed, 3)}) + M = Meth([], Signed) + def m_(self): + return self.a + m = meth(M, _name="m", _callable=m_) + addMethods(C, {"m": m}) + + def f(): + c = new(C) + return c.m() + + g = gengraph(f) + rettype = g.getreturnvar().concretetype + assert rettype == Signed From dialtone at codespeak.net Fri Oct 14 16:56:32 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Fri, 14 Oct 2005 16:56:32 +0200 (CEST) Subject: [pypy-svn] r18554 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051014145632.A6DD527B57@code1.codespeak.net> Author: dialtone Date: Fri Oct 14 16:56:30 2005 New Revision: 18554 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: (valentino, afa) add missing test for fromfd whitespace cleanup change wrong definition of _socket.fromfd Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Fri Oct 14 16:56:30 2005 @@ -77,11 +77,11 @@ Create a socket object from the given file descriptor. The remaining arguments are the same as for socket(). """ - if proto is None: + if w_proto is None: return space.wrap(socket.fromfd(fd, family, type)) else: - return space.wrap(socket.fromfd(fd, family, type, space.int_w(proto))) -fromfd.unwrap_spec = [ObjSpace, int, int, int, int] + return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto))) +fromfd.unwrap_spec = [ObjSpace, int, int, int, W_Root] # fromfd socketpair # ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Fri Oct 14 16:56:30 2005 @@ -1,12 +1,14 @@ -from pypy.objspace.std import StdObjSpace +from pypy.objspace.std import StdObjSpace from pypy.tool.udir import udir import py import socket, sys -def setup_module(mod): +def setup_module(mod): mod.space = StdObjSpace(usemodules=['_socket']) mod.w_socket = space.appexec([], "(): import _socket as m; return m") - + mod.path = udir.join('fd') + mod.path.write('fo') + def test_gethostname(): host = space.appexec([w_socket], "(_socket): return _socket.gethostname()") assert space.unwrap(host) == socket.gethostname() @@ -62,7 +64,7 @@ except TypeError: return 'OK' """) - assert space.unwrap(name) == 'OK' + assert space.unwrap(name) == 'OK' # 1 arg version name = space.appexec([w_socket, space.wrap(port)], "(_socket, port): return _socket.getservbyport(port)") @@ -73,9 +75,24 @@ num = space.appexec([w_socket, space.wrap(name)], "(_socket, name): return _socket.getprotobyname(name)") assert space.unwrap(num) == socket.IPPROTO_TCP - def test_has_ipv6(): res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") assert space.unwrap(res) == socket.has_ipv6 +def test_fromfd(): + # XXX review + orig_fd = path.open() + fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), + space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM), + space.wrap(0)], + """(_socket, fd, family, type, proto): + return _socket.fromfd(fd, family, type, proto)""") + + assert space.unwrap(fd).fileno() + fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), + space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM)], + """(_socket, fd, family, type): + return _socket.fromfd(fd, family, type)""") + + assert space.unwrap(fd).fileno() From boria at codespeak.net Fri Oct 14 17:11:42 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 17:11:42 +0200 (CEST) Subject: [pypy-svn] r18555 - pypy/branch/hl-backend/pypy/rpython/ootypesystem/test Message-ID: <20051014151142.898C527B57@code1.codespeak.net> Author: boria Date: Fri Oct 14 17:11:42 2005 New Revision: 18555 Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooclean.py Log: * Rename failing tests in preparation to merging to trunk. Modified: pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/branch/hl-backend/pypy/rpython/ootypesystem/test/test_ooclean.py Fri Oct 14 17:11:42 2005 @@ -26,7 +26,7 @@ return a + b specialize(f, [int, int]) -def test_simple_call(): +def inprogress_test_simple_call(): def f(a, b): return a + b @@ -38,7 +38,7 @@ class EmptyBase(object): pass -def test_simple(): +def inprogress_test_simple_empty_base(): def dummyfn(): x = EmptyBase() return x From afa at codespeak.net Fri Oct 14 17:13:10 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 14 Oct 2005 17:13:10 +0200 (CEST) Subject: [pypy-svn] r18556 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051014151310.A314727B57@code1.codespeak.net> Author: afa Date: Fri Oct 14 17:13:08 2005 New Revision: 18556 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: valentino, afa: more socket functions, and tests Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Fri Oct 14 17:13:08 2005 @@ -1,89 +1,175 @@ - -import socket -from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped - -def gethostname(space): - """gethostname() -> string - - Return the current host name. - """ - return space.wrap(socket.gethostname()) -gethostname.unwrap_spec = [ObjSpace] - -def gethostbyname(space, name): - """gethostbyname(host) -> address - - Return the IP address (a string of the form '255.255.255.255') for a host. - """ - return space.wrap(socket.gethostbyname(name)) -gethostbyname.unwrap_spec = [ObjSpace, str] - -def gethostbyname_ex(space, name): - """gethostbyname_ex(host) -> (name, aliaslist, addresslist) - - Return the true host name, a list of aliases, and a list of IP addresses, - for a host. The host argument is a string giving a host name or IP number. - """ - return space.wrap(socket.gethostbyname_ex(name)) -gethostbyname_ex.unwrap_spec = [ObjSpace, str] - -def gethostbyaddr(space, ip_num): - """gethostbyaddr(host) -> (name, aliaslist, addresslist) - - Return the true host name, a list of aliases, and a list of IP addresses, - for a host. The host argument is a string giving a host name or IP number. - """ - return space.wrap(socket.gethostbyaddr(ip_num)) -gethostbyaddr.unwrap_spec = [ObjSpace, str] - -def getservbyname(space, name, w_proto=NoneNotWrapped): - """getservbyname(servicename[, protocolname]) -> integer - - Return a port number from a service name and protocol name. - The optional protocol name, if given, should be 'tcp' or 'udp', - otherwise any protocol will match. - """ - if w_proto is None: - return space.wrap(socket.getservbyname(name)) - else: - return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) -getservbyname.unwrap_spec = [ObjSpace, str, W_Root] - -def getservbyport(space, port, w_proto=NoneNotWrapped): - """getservbyport(port[, protocolname]) -> string - - Return the service name from a port number and protocol name. - The optional protocol name, if given, should be 'tcp' or 'udp', - otherwise any protocol will match. - """ - if w_proto is None: - return space.wrap(socket.getservbyport(port)) - else: - return space.wrap(socket.getservbyport(port, space.str_w(w_proto))) -getservbyport.unwrap_spec = [ObjSpace, int, W_Root] - -def getprotobyname(space, name): - """getprotobyname(name) -> integer - - Return the protocol number for the named protocol. (Rarely used.) - """ - return space.wrap(socket.getprotobyname(name)) -getprotobyname.unwrap_spec = [ObjSpace, str] - -def fromfd(space, fd, family, type, w_proto=NoneNotWrapped): - """fromfd(fd, family, type[, proto]) -> socket object - - Create a socket object from the given file descriptor. - The remaining arguments are the same as for socket(). - """ - if w_proto is None: - return space.wrap(socket.fromfd(fd, family, type)) - else: - return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto))) -fromfd.unwrap_spec = [ObjSpace, int, int, int, W_Root] - -# fromfd socketpair -# ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop -# getaddrinfo getnameinfo -# getdefaulttimeout setdefaulttimeout + +import socket +from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped + +def gethostname(space): + """gethostname() -> string + + Return the current host name. + """ + return space.wrap(socket.gethostname()) +gethostname.unwrap_spec = [ObjSpace] + +def gethostbyname(space, name): + """gethostbyname(host) -> address + + Return the IP address (a string of the form '255.255.255.255') for a host. + """ + return space.wrap(socket.gethostbyname(name)) +gethostbyname.unwrap_spec = [ObjSpace, str] + +def gethostbyname_ex(space, name): + """gethostbyname_ex(host) -> (name, aliaslist, addresslist) + + Return the true host name, a list of aliases, and a list of IP addresses, + for a host. The host argument is a string giving a host name or IP number. + """ + return space.wrap(socket.gethostbyname_ex(name)) +gethostbyname_ex.unwrap_spec = [ObjSpace, str] + +def gethostbyaddr(space, ip_num): + """gethostbyaddr(host) -> (name, aliaslist, addresslist) + + Return the true host name, a list of aliases, and a list of IP addresses, + for a host. The host argument is a string giving a host name or IP number. + """ + return space.wrap(socket.gethostbyaddr(ip_num)) +gethostbyaddr.unwrap_spec = [ObjSpace, str] + +def getservbyname(space, name, w_proto=NoneNotWrapped): + """getservbyname(servicename[, protocolname]) -> integer + + Return a port number from a service name and protocol name. + The optional protocol name, if given, should be 'tcp' or 'udp', + otherwise any protocol will match. + """ + if w_proto is None: + return space.wrap(socket.getservbyname(name)) + else: + return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) +getservbyname.unwrap_spec = [ObjSpace, str, W_Root] + +def getservbyport(space, port, w_proto=NoneNotWrapped): + """getservbyport(port[, protocolname]) -> string + + Return the service name from a port number and protocol name. + The optional protocol name, if given, should be 'tcp' or 'udp', + otherwise any protocol will match. + """ + if w_proto is None: + return space.wrap(socket.getservbyport(port)) + else: + return space.wrap(socket.getservbyport(port, space.str_w(w_proto))) +getservbyport.unwrap_spec = [ObjSpace, int, W_Root] + +def getprotobyname(space, name): + """getprotobyname(name) -> integer + + Return the protocol number for the named protocol. (Rarely used.) + """ + return space.wrap(socket.getprotobyname(name)) +getprotobyname.unwrap_spec = [ObjSpace, str] + +def fromfd(space, fd, family, type, w_proto=NoneNotWrapped): + """fromfd(fd, family, type[, proto]) -> socket object + + Create a socket object from the given file descriptor. + The remaining arguments are the same as for socket(). + """ + if w_proto is None: + return space.wrap(socket.fromfd(fd, family, type)) + else: + return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto))) +fromfd.unwrap_spec = [ObjSpace, int, int, int, W_Root] + +def socketpair(space, w_family=NoneNotWrapped, w_type=NoneNotWrapped, w_proto=NoneNotWrapped): + """socketpair([family[, type[, proto]]]) -> (socket object, socket object) + + Create a pair of socket objects from the sockets returned by the platform + socketpair() function. + The arguments are the same as for socket() except the default family is + AF_UNIX if defined on the platform; otherwise, the default is AF_INET. + """ + if w_family is None: + return space.wrap(socket.socketpair()) + elif w_type is None: + return space.wrap(socket.socketpair(space.int_w(w_family))) + elif w_proto is None: + return space.wrap(socket.socketpair(space.int_w(w_family), + space.int_w(w_type))) + else: + return space.wrap(socket.socketpair(space.int_w(w_family), + space.int_w(w_type), + space.int_w(w_proto))) +socketpair.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root] + +def ntohs(space, x): + """ntohs(integer) -> integer + + Convert a 16-bit integer from network to host byte order. + """ + return space.wrap(socket.ntohs(x)) +ntohs.unwrap_spec = [ObjSpace, int] + +def ntohl(space, x): + """ntohl(integer) -> integer + + Convert a 32-bit integer from network to host byte order. + """ + return space.wrap(socket.ntohl(x)) +ntohl.unwrap_spec = [ObjSpace, int] + +def htons(space, x): + """htons(integer) -> integer + + Convert a 16-bit integer from host to network byte order. + """ + return space.wrap(socket.htons(x)) +htons.unwrap_spec = [ObjSpace, int] + +def htonl(space, x): + """htonl(integer) -> integer + + Convert a 32-bit integer from host to network byte order. + """ + return space.wrap(socket.htonl(x)) +htonl.unwrap_spec = [ObjSpace, int] + +def inet_aton(space, ip): + """inet_aton(string) -> packed 32-bit IP representation + + Convert an IP address in string format (123.45.67.89) to the 32-bit packed + binary format used in low-level network functions. + """ + return space.wrap(socket.inet_aton(ip)) +inet_aton.unwrap_spec = [ObjSpace, str] + +def inet_ntoa(space, packed): + """inet_ntoa(packed_ip) -> ip_address_string + + Convert an IP address from 32-bit packed binary format to string format + """ + return space.wrap(socket.inet_ntoa(packed)) +inet_ntoa.unwrap_spec = [ObjSpace, str] + +def inet_pton(space, af, ip): + """inet_pton(af, ip) -> packed IP address string + + Convert an IP address from string format to a packed string suitable + for use with low-level network functions. + """ + return space.wrap(socket.inet_pton(af, ip)) +inet_pton.unwrap_spec = [ObjSpace, int, str] + +def inet_ntop(space, af, packed): + """inet_ntop(af, packed_ip) -> string formatted IP address + + Convert a packed IP address of the given family to string format. + """ + return space.wrap(socket.inet_ntop(af, packed)) +inet_ntop.unwrap_spec = [ObjSpace, int, str] + + +# getaddrinfo getnameinfo +# getdefaulttimeout setdefaulttimeout Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Fri Oct 14 17:13:08 2005 @@ -72,16 +72,14 @@ def test_getprotobyname(): name = "tcp" - num = space.appexec([w_socket, space.wrap(name)], + w_n = space.appexec([w_socket, space.wrap(name)], "(_socket, name): return _socket.getprotobyname(name)") - assert space.unwrap(num) == socket.IPPROTO_TCP - -def test_has_ipv6(): - res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") - assert space.unwrap(res) == socket.has_ipv6 + assert space.unwrap(w_n) == socket.IPPROTO_TCP def test_fromfd(): # XXX review + if not hasattr(socket, 'fromfd'): + py.test.skip("No socket.fromfd on this platform") orig_fd = path.open() fd = space.appexec([w_socket, space.wrap(orig_fd.fileno()), space.wrap(socket.AF_INET), space.wrap(socket.SOCK_STREAM), @@ -96,3 +94,49 @@ return _socket.fromfd(fd, family, type)""") assert space.unwrap(fd).fileno() + +def test_ntohs(): + w_n = space.appexec([w_socket, space.wrap(125)], + "(_socket, x): return _socket.ntohs(x)") + assert space.unwrap(w_n) == socket.ntohs(125) + +def test_ntohl(): + w_n = space.appexec([w_socket, space.wrap(125)], + "(_socket, x): return _socket.ntohl(x)") + assert space.unwrap(w_n) == socket.ntohl(125) + +def test_htons(): + w_n = space.appexec([w_socket, space.wrap(125)], + "(_socket, x): return _socket.htons(x)") + assert space.unwrap(w_n) == socket.htons(125) + +def test_htonl(): + w_n = space.appexec([w_socket, space.wrap(125)], + "(_socket, x): return _socket.htonl(x)") + assert space.unwrap(w_n) == socket.htonl(125) + +def test_packed_ip(): + ip = '123.45.67.89' + packed = socket.inet_aton(ip) + w_p = space.appexec([w_socket, space.wrap(ip)], + "(_socket, ip): return _socket.inet_aton(ip)") + assert space.unwrap(w_p) == packed + w_ip = space.appexec([w_socket, space.wrap(packed)], + "(_socket, p): return _socket.inet_ntoa(p)") + assert space.unwrap(w_ip) == ip + +def test_pton(): + if not hasattr(socket, 'inet_pton'): + py.test.skip('No socket.(inet_pton|inet_ntop) on this platform') + w_p = space.appexec([w_socket, space.wrap(ip)], + "(_socket, ip): return _socket.inet_pton(_socket.AF_INET, ip)") + assert space.unwrap(w_p) == packed + w_ip = space.appexec([w_socket, space.wrap(packed)], + "(_socket, p): return _socket.inet_ntop(_socket.AF_INET, p)") + assert space.unwrap(w_ip) == ip + + +def test_has_ipv6(): + res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") + assert space.unwrap(res) == socket.has_ipv6 + From dialtone at codespeak.net Fri Oct 14 17:14:55 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Fri, 14 Oct 2005 17:14:55 +0200 (CEST) Subject: [pypy-svn] r18557 - pypy/dist/pypy/module/_socket/test Message-ID: <20051014151455.07BBE27B57@code1.codespeak.net> Author: dialtone Date: Fri Oct 14 17:14:53 2005 New Revision: 18557 Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py Log: (valentino, afa) whitespace cleanup test ntop, pton pass Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Fri Oct 14 17:14:53 2005 @@ -126,6 +126,8 @@ assert space.unwrap(w_ip) == ip def test_pton(): + ip = '123.45.67.89' + packed = socket.inet_aton(ip) if not hasattr(socket, 'inet_pton'): py.test.skip('No socket.(inet_pton|inet_ntop) on this platform') w_p = space.appexec([w_socket, space.wrap(ip)], @@ -134,7 +136,6 @@ w_ip = space.appexec([w_socket, space.wrap(packed)], "(_socket, p): return _socket.inet_ntop(_socket.AF_INET, p)") assert space.unwrap(w_ip) == ip - def test_has_ipv6(): res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") From cfbolz at codespeak.net Fri Oct 14 17:20:36 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 14 Oct 2005 17:20:36 +0200 (CEST) Subject: [pypy-svn] r18558 - in pypy/dist/pypy/rpython/llinterpreter: . test Message-ID: <20051014152036.08C6A27B58@code1.codespeak.net> Author: cfbolz Date: Fri Oct 14 17:20:34 2005 New Revision: 18558 Added: pypy/dist/pypy/rpython/llinterpreter/ pypy/dist/pypy/rpython/llinterpreter/llinterpreter.py pypy/dist/pypy/rpython/llinterpreter/model.py pypy/dist/pypy/rpython/llinterpreter/test/ pypy/dist/pypy/rpython/llinterpreter/test/__init__.py pypy/dist/pypy/rpython/llinterpreter/test/test_llinterpreter.py Log: (cfbolz, hpk, armin): first simplicistic try of an l3interpreter. Added: pypy/dist/pypy/rpython/llinterpreter/llinterpreter.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/llinterpreter/llinterpreter.py Fri Oct 14 17:20:34 2005 @@ -0,0 +1,59 @@ +from pypy.rpython.llinterpreter import model +from pypy.rpython.memory import lladdress + +class LLException(Exception): + def __init__(self): + pass + +class LLInterpreter(object): + def eval_graph_int(self, graph, args): + frame = LLFrame(graph, self) + returnlink = frame.eval(args) + return frame.get_int(0) + +class LLFrame(object): + def __init__(self, graph, lli): + self.llinterpreter = lli + self.graph = graph + self.int_vars = [0] * graph.max_num_ints + + def eval(self, args): + assert len(args) == 0, "not implemented, XXX" + link = self.graph.startlink +# self.fill_input_arg(... + while type(link) == model.Link: + link = self.eval_block(link.target) + self.copy_link_vars(link) + return link + + def eval_block(self, block): + for op in block.operations: + op.opimpl(self, op.result, op.args) + exitswitch = block.exitswitch + if exitswitch >= 0: + link = block.exits[self.int_vars[exitswitch]] + return link + return block.exits[0] + + + def copy_link_vars(self, link): + for i in range(0, len(link.move_int_registers), 2): + source = link.move_int_registers[i] + target = link.move_int_registers[i + 1] + self.set_int(target, self.get_int(source)) + + def get_int(self, index): + if index < 0: + return self.graph.constants_int[~index] + else: + return self.int_vars[index] + + def set_int(self, index, val): + self.int_vars[index] = val + + def op_int_add(self, result, args): + int1 = self.get_int(args[0]) + int2 = self.get_int(args[1]) + self.set_int(result, int1 + int2) + + Added: pypy/dist/pypy/rpython/llinterpreter/model.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/llinterpreter/model.py Fri Oct 14 17:20:34 2005 @@ -0,0 +1,145 @@ +from pypy.rpython.memory import lladdress +from pypy.objspace.flow import model as flowmodel +from pypy.rpython import lltype + +very_low_level_ops = [ + #operations with adresses: + 'adr_add', 'adr_delta', 'adr_eq', 'adr_ge', 'adr_gt', 'adr_le', + 'adr_lt', 'adr_ne', 'adr_sub', + + #operations with bools: + 'bool_not', + + #casts: + 'cast_bool_to_float', 'cast_bool_to_int', 'cast_char_to_int', + 'cast_float_to_int', 'cast_int_to_char', 'cast_int_to_float', + 'cast_int_to_uint', 'cast_int_to_unichar', 'cast_pointer', + 'cast_ptr_to_int', 'cast_uint_to_int', 'cast_unichar_to_int', + + #operations with chars: + 'char_eq', 'char_ge', 'char_gt', 'char_le', 'char_lt', 'char_ne', + + #calls: + 'direct_call', + + #flavored memory operations: + 'flavored_free', 'flavored_malloc', + + #float operations: + 'float_abs', 'float_add', 'float_div', 'float_eq', 'float_floor', + 'float_floordiv', 'float_fmod', 'float_ge', 'float_gt', 'float_invert', + 'float_is_true', 'float_le', 'float_lt', 'float_mod', 'float_mul', + 'float_ne', 'float_neg', 'float_sub', 'float_truediv', + + #array operations: + 'getarrayitem', 'getarraysize', 'getarraysubstruct', 'setarrayitem', + + #struct operations: + 'getfield', 'getsubstruct', 'setfield', + + #integer operations: + 'int_abs', 'int_abs_ovf', 'int_add', 'int_add_ovf', 'int_and', + 'int_and_ovf', 'int_div', 'int_div_ovf', 'int_eq', 'int_eq_ovf', + 'int_floordiv', 'int_floordiv_ovf', 'int_floordiv_ovf_zer', 'int_ge', + 'int_ge_ovf', 'int_gt', 'int_gt_ovf', 'int_invert', 'int_invert_ovf', + 'int_is_true', 'int_is_true_ovf', 'int_le', 'int_le_ovf', 'int_lshift', + 'int_lshift_ovf', 'int_lt', 'int_lt_ovf', 'int_mod', 'int_mod_ovf', + 'int_mod_ovf_zer', 'int_mul', 'int_mul_ovf', 'int_ne', 'int_ne_ovf', + 'int_neg', 'int_neg_ovf', 'int_or', 'int_or_ovf', 'int_rshift', + 'int_rshift_ovf', 'int_sub', 'int_sub_ovf', 'int_truediv', + 'int_truediv_ovf', 'int_xor', 'int_xor_ovf', + + #regular object memory operations: + 'keepalive', 'malloc', 'malloc_varsize', + + #pointer operations: + 'ptr_eq', 'ptr_iszero', 'ptr_ne', 'ptr_nonzero', + + #raw memory operations + 'raw_free', 'raw_load', 'raw_malloc', 'raw_memcopy', 'raw_store', + + #same_as: + 'same_as', + + #operations with unsigned integers: + 'uint_abs', 'uint_add', 'uint_and', 'uint_div', 'uint_eq', + 'uint_floordiv', 'uint_ge', 'uint_gt', 'uint_invert', 'uint_is_true', + 'uint_le', 'uint_lshift', 'uint_lt', 'uint_mod', 'uint_mul', 'uint_ne', + 'uint_neg', 'uint_or', 'uint_rshift', 'uint_sub', 'uint_truediv', + 'uint_xor', + + #operations with unicode characters + 'unichar_eq', 'unichar_ne' + ] + + + + +primitives = [lltype.Signed, lltype.Unsigned, lltype.Float, lltype.Char, + lltype.UniChar, lladdress.Address, lltype.Void] + +primitive_to_number = {} +for i, p in enumerate(primitives): + primitive_to_number[p] = -i - 1 +del p + + +# possible values for exitswitch: +ONE_EXIT = -1 +LAST_EXCEPTION = -2 + +class Operation(object): + def __init__(self, opimpl, result, args): + self.opimpl = opimpl # unbound method of LLFrame + self.args = args # list of ints: how to represent constants? + self.result = result # resulting variable + +class Link(object): + def __init__(self, target, args, exitcase=None): + self.target = target # target is a Block + self.intargs = args # args is a list of ints, same meaning as Operation.args + self.exitcase = exitcase # NULL for non-exceptional case + # address of exception class else + self.move_int_registers = [] + +class ReturnLink(Link): + pass + +class StartLink(Link): + pass + +class Block(object): + def __init__(self, int_a, exitswitch, exits): + self.operations = [] # list of Operations + self.exitswitch = exitswitch # positives are variables + # negatives see above + self.exits = exits # list of Links + self.int_inputargs = int_a # list of ints + +class Graph(object): + def __init__(self, name, startlink): + self.name = name # string + self.startlink = startlink # Block + self.constants_int = [] + self.max_num_ints = 17 #XXX calculate this + + def set_constants_int(self, constants): + self.constants_int = constants + + def blocklist(self): + result = [] + pending = [self.startblock] + seen = {} + while len(pending): + block = pending.pop() + if block in seen: + continue + result.append(block) + for i in range(len(block.exits)): + pending.append(block.exits[i].target) + return result + +class Globals(object): + def __init__(self): + self.graphs = [] # list of Graphs + Added: pypy/dist/pypy/rpython/llinterpreter/test/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/llinterpreter/test/__init__.py Fri Oct 14 17:20:34 2005 @@ -0,0 +1 @@ +# Added: pypy/dist/pypy/rpython/llinterpreter/test/test_llinterpreter.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/llinterpreter/test/test_llinterpreter.py Fri Oct 14 17:20:34 2005 @@ -0,0 +1,17 @@ +from pypy.rpython.llinterpreter import llinterpreter +from pypy.rpython.llinterpreter import model + +def test_very_simple(): + op = model.Operation(llinterpreter.LLFrame.op_int_add, 0, [-1, -2]) + returnlink = model.ReturnLink(None, []) + block = model.Block([], model.ONE_EXIT, [returnlink]) + block.operations.append(op) + startlink = model.Link(block, []) + graph = model.Graph("testgraph", startlink) + graph.set_constants_int([3, 4]) + g = model.Globals() + g.graphs = [graph] + l3interp = llinterpreter.LLInterpreter() + result = l3interp.eval_graph_int(graph, []) + assert result == 7 + From dialtone at codespeak.net Fri Oct 14 17:22:12 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Fri, 14 Oct 2005 17:22:12 +0200 (CEST) Subject: [pypy-svn] r18559 - in pypy/dist/pypy/module: Numeric _socket _socket/test Message-ID: <20051014152212.F39B727B58@code1.codespeak.net> Author: dialtone Date: Fri Oct 14 17:22:10 2005 New Revision: 18559 Modified: pypy/dist/pypy/module/Numeric/ (props changed) pypy/dist/pypy/module/_socket/__init__.py (props changed) pypy/dist/pypy/module/_socket/app_socket.py (props changed) pypy/dist/pypy/module/_socket/test/test_socket2.py (props changed) Log: FIXEOL From ericvrp at codespeak.net Fri Oct 14 17:22:44 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 14 Oct 2005 17:22:44 +0200 (CEST) Subject: [pypy-svn] r18560 - pypy/dist/pypy/translator/js Message-ID: <20051014152244.E3D9327B5C@code1.codespeak.net> Author: ericvrp Date: Fri Oct 14 17:22:43 2005 New Revision: 18560 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/node.py pypy/dist/pypy/translator/js/opaquenode.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py Log: * Even more simplifications of what gets written. * working on forward declartion and global data. [90 passed, 73 failed] Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Fri Oct 14 17:22:43 2005 @@ -39,14 +39,14 @@ # ______________________________________________________________________ # entry points from genllvm # - def writedatatypedecl(self, codewriter): - codewriter.arraydef(self.ref, - 'int', - self.db.repr_type(self.arraytype)) - - def writedecl(self, codewriter): - # declaration for constructor - codewriter.declare(self.constructor_decl) + #def writedatatypedecl(self, codewriter): + # codewriter.arraydef(self.ref, + # 'int', + # self.db.repr_type(self.arraytype)) + + #def writedecl(self, codewriter): + # # declaration for constructor + # codewriter.declare(self.constructor_decl) class VoidArrayTypeNode(LLVMNode): @@ -58,9 +58,9 @@ self.array = array self.ref = "arraytype_Void" - def writedatatypedecl(self, codewriter): - td = "%s = type { int }" % self.ref - codewriter.append(td) + #def writedatatypedecl(self, codewriter): + # td = "%s = type { int }" % self.ref + # codewriter.append(td) class ArrayNode(ConstantLLVMNode): """ An arraynode. Elements can be @@ -91,6 +91,12 @@ if p is not None: self.db.prepare_constant(lltype.typeOf(p), p) + def writedecl(self, codewriter): + if self.arraytype is lltype.Char: #or use seperate nodetype + codewriter.declare(self.ref + ' = new String()') + else: + codewriter.declare(self.ref + ' = new Array()') + def get_length(self): """ returns logical length of array """ items = self.value.items @@ -157,10 +163,6 @@ def get_arrayvalue(self): items = self.value.items item_length = len(items) - #don't force null termination anymore! - #if item_length == 0 or items[-1] != chr(0): - # items = items + [chr(0)] - # item_length += 1 s = [] for c in items: if ord(c) in StrArrayNode.printables: Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Fri Oct 14 17:22:43 2005 @@ -54,18 +54,20 @@ self.llvm(line, 0) def structdef(self, name, typereprs): - self.llvm("%s = type { %s }" %(name, ", ".join(typereprs)), 0) + #self.llvm("%s = type { %s }" %(name, ", ".join(typereprs)), 0) + pass def arraydef(self, name, lentype, typerepr): - self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr), 0) + #self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr), 0) + pass def funcdef(self, name, rettyperepr, argtypereprs): - self.llvm("%s = type %s (%s)" % (name, rettyperepr, - ", ".join(argtypereprs)), 0) + #self.llvm("%s = type %s (%s)" % (name, rettyperepr, + # ", ".join(argtypereprs)), 0) + pass def declare(self, decl): - #self.llvm("declare %s" % decl, 0) - pass + self.append(decl, 0) def startimpl(self): #self.llvm("implementation", 0) @@ -88,6 +90,8 @@ src = 'false' elif src == 'True': src = 'true' + elif src == 'None': + src = 'undefined' if dest != src: self.append('%s = %s' % (dest, src), indentation_level) Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Fri Oct 14 17:22:43 2005 @@ -242,7 +242,7 @@ if isinstance(type_, lltype.Primitive): return self.primitives[type_] elif isinstance(type_, lltype.Ptr): - return self.repr_type(type_.TO) + '*' + return '' #self.repr_type(type_.TO) + 'XXX*' else: raise TypeError("cannot represent %r" %(type_,)) @@ -334,13 +334,13 @@ # __________________________________________________________ # 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_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 get_childref(self, parent, child): node = self.obj2node[parent] Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Fri Oct 14 17:22:43 2005 @@ -31,10 +31,10 @@ self.db.prepare_type(self.type_.RESULT) self.db.prepare_type_multi(self.type_._trueargs()) - def writedatatypedecl(self, codewriter): - 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) + #def writedatatypedecl(self, codewriter): + # 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): __slots__ = "db value ref graph blockindex".split() @@ -77,8 +77,8 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedecl(self, codewriter): - codewriter.declare(self.getdecl()) + #def writedecl(self, codewriter): + # codewriter.declare(self.getdecl()) def writeimpl(self, codewriter): graph = self.graph Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Fri Oct 14 17:22:43 2005 @@ -4,6 +4,7 @@ http://webreference.com/programming/javascript/ http://mochikit.com/ http://www.mozilla.org/js/spidermonkey/ + svn co http://codespeak.net/svn/kupu/trunk/ecmaunit ''' #import os @@ -77,7 +78,7 @@ # codewriter.comment("External Function Declarations") # codewriter.append(llexterns_header) - codewriter.comment("Type Declarations", 0) + #codewriter.comment("Type Declarations", 0) #for c_name, obj in extern_decls: # if isinstance(obj, lltype.LowLevelType): # if isinstance(obj, lltype.Ptr): @@ -85,26 +86,24 @@ # l = "%%%s = type %s" % (c_name, self.db.repr_type(obj)) # codewriter.append(l) + codewriter.comment("Function Implementation", 0) + for typ_decl in self.db.getnodes(): + typ_decl.writeimpl(codewriter) + + codewriter.comment("Forward Declarations", 0) + #for typ_decl in self.db.getnodes(): + # typ_decl.writedatatypedecl(codewriter) for typ_decl in self.db.getnodes(): - typ_decl.writedatatypedecl(codewriter) + typ_decl.writedecl(codewriter) codewriter.comment("Global Data", 0) for typ_decl in self.db.getnodes(): typ_decl.writeglobalconstants(codewriter) - codewriter.comment("Function Prototypes", 0) + #codewriter.comment("Function Prototypes", 0) #codewriter.append(extdeclarations) #codewriter.append(self.gcpolicy.declarations()) - for typ_decl in self.db.getnodes(): - typ_decl.writedecl(codewriter) - - codewriter.comment("Function Implementation", 0) - codewriter.startimpl() - - for typ_decl in self.db.getnodes(): - typ_decl.writeimpl(codewriter) - pypy_prefix = '' #pypy_ #codewriter.append(self.exceptionpolicy.llvmcode(self.entrynode)) Modified: pypy/dist/pypy/translator/js/node.py ============================================================================== --- pypy/dist/pypy/translator/js/node.py (original) +++ pypy/dist/pypy/translator/js/node.py Fri Oct 14 17:22:43 2005 @@ -32,10 +32,10 @@ pass # __________________ before "implementation" ____________________ - def writedatatypedecl(self, codewriter): - """ write out declare names of data types - (structs/arrays/function pointers) - """ + #def writedatatypedecl(self, codewriter): + # """ write out declare names of data types + # (structs/arrays/function pointers) + # """ def writeglobalconstants(self, codewriter): """ write out global values. """ Modified: pypy/dist/pypy/translator/js/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/js/opaquenode.py (original) +++ pypy/dist/pypy/translator/js/opaquenode.py Fri Oct 14 17:22:43 2005 @@ -15,9 +15,9 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedatatypedecl(self, codewriter): - # XXX Dummy - not sure what what we want - codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *']) + #def writedatatypedecl(self, codewriter): + # # XXX Dummy - not sure what what we want + # codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *']) class OpaqueNode(ConstantLLVMNode): Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Fri Oct 14 17:22:43 2005 @@ -254,8 +254,8 @@ 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:]) - if self.db.is_function_ptr(op.result): - returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) + #if self.db.is_function_ptr(op.result): + # returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) self.codewriter.call(targetvar,returntype,functionref,argrefs,argtypes) def last_exception_type_ptr(self, op): @@ -297,8 +297,8 @@ block_label = self.node.blockindex[self.block] exc_label = block_label + '_exception_handling' - if self.db.is_function_ptr(op.result): #use longhand form - returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) + #if self.db.is_function_ptr(op.result): #use longhand form + # returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) self.codewriter.call(targetvar, returntype, functionref, argrefs, argtypes, none_label, exc_label) Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Fri Oct 14 17:22:43 2005 @@ -5,6 +5,11 @@ log = log.structnode +def _rename_reserved_keyword(name): + if name in 'if then else function for while witch continue break super int bool Array String Struct Number'.split(): + name += '_' + return name + class StructTypeNode(LLVMNode): __slots__ = "db struct ref name".split() @@ -32,9 +37,9 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedatatypedecl(self, codewriter): - fields_types = [self.db.repr_type(f) for f in self._fields()] - codewriter.structdef(self.ref, fields_types) + #def writedatatypedecl(self, codewriter): + # fields_types = [self.db.repr_type(f) for f in self._fields()] + # codewriter.structdef(self.ref, fields_types) class StructVarsizeTypeNode(StructTypeNode): __slots__ = "constructor_ref constructor_decl".split() @@ -53,9 +58,9 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedecl(self, codewriter): - # declaration for constructor - codewriter.declare(self.constructor_decl) + #def writedecl(self, codewriter): + # # declaration for constructor + # codewriter.declare(self.constructor_decl) def writeimpl(self, codewriter): log.writeimpl(self.ref) @@ -112,22 +117,26 @@ p, c = lltype.parentlink(self.value) if p is not None: self.db.prepare_constant(lltype.typeOf(p), p) - + + def writedecl(self, codewriter): + codewriter.declare(self.ref + ' = new Object()') + def get_typerepr(self): return self.db.repr_type(self.structtype) def get_childref(self, index): - pos = 0 - found = False - for name in self.structtype._names_without_voids(): - if name == index: - found = True - break - pos += 1 - return "getelementptr(%s* %s, int 0, uint %s)" %( - self.get_typerepr(), - self.get_ref(), - pos) + return self.get_ref() #XXX what to do with index? + #pos = 0 + #found = False + #for name in self.structtype._names_without_voids(): + # if name == index: + # found = True + # break + # pos += 1 + #return "getelementptr(%s* %s, int 0, uint %s)" %( + # self.get_typerepr(), + # self.get_ref(), + # pos) def get_ref(self): """ Returns a reference as used for operations in blocks. """ @@ -144,12 +153,13 @@ def get_pbcref(self, toptr): """ Returns a reference as used per pbc. """ return self.get_ref() - + def constantvalue(self): """ Returns the constant representation for this node. """ vars = [] for i, value in enumerate(self._getvalues()): name = self._get_types[i][0] + name = _rename_reserved_keyword(name) var = (name, str(value)) vars.append(var) return "({%s})" % ", ".join(["%s:%s" % var for var in vars]) From hpk at codespeak.net Fri Oct 14 17:25:36 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 14 Oct 2005 17:25:36 +0200 (CEST) Subject: [pypy-svn] r18561 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051014152536.A499127B58@code1.codespeak.net> Author: hpk Date: Fri Oct 14 17:25:36 2005 New Revision: 18561 Added: pypy/dist/pypy/rpython/l3interp/ - copied from r18558, pypy/dist/pypy/rpython/llinterpreter/ Modified: pypy/dist/pypy/rpython/l3interp/test/test_llinterpreter.py Log: intermediate checkin Modified: pypy/dist/pypy/rpython/l3interp/test/test_llinterpreter.py ============================================================================== --- pypy/dist/pypy/rpython/llinterpreter/test/test_llinterpreter.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_llinterpreter.py Fri Oct 14 17:25:36 2005 @@ -1,8 +1,8 @@ -from pypy.rpython.llinterpreter import llinterpreter -from pypy.rpython.llinterpreter import model +from pypy.rpython.l3interp import l3interp +from pypy.rpython.l3interp import model def test_very_simple(): - op = model.Operation(llinterpreter.LLFrame.op_int_add, 0, [-1, -2]) + op = model.Operation(l3interp.LLFrame.op_int_add, 0, [-1, -2]) returnlink = model.ReturnLink(None, []) block = model.Block([], model.ONE_EXIT, [returnlink]) block.operations.append(op) @@ -11,7 +11,7 @@ graph.set_constants_int([3, 4]) g = model.Globals() g.graphs = [graph] - l3interp = llinterpreter.LLInterpreter() + l3interp = l3interp.LLInterpreter() result = l3interp.eval_graph_int(graph, []) assert result == 7 From hpk at codespeak.net Fri Oct 14 17:30:06 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 14 Oct 2005 17:30:06 +0200 (CEST) Subject: [pypy-svn] r18562 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051014153006.68E8027B58@code1.codespeak.net> Author: hpk Date: Fri Oct 14 17:30:05 2005 New Revision: 18562 Added: pypy/dist/pypy/rpython/l3interp/__init__.py (contents, props changed) pypy/dist/pypy/rpython/l3interp/l3interp.py - copied, changed from r18561, pypy/dist/pypy/rpython/l3interp/llinterpreter.py pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py - copied, changed from r18561, pypy/dist/pypy/rpython/l3interp/test/test_llinterpreter.py Removed: pypy/dist/pypy/rpython/l3interp/llinterpreter.py pypy/dist/pypy/rpython/l3interp/test/test_llinterpreter.py Log: (hpk, cfbolz) renaming in order to make it more distinct from the ll-interpreter. Now it's the lower low level interpreter (l3) ... Added: pypy/dist/pypy/rpython/l3interp/__init__.py ============================================================================== From hpk at codespeak.net Fri Oct 14 17:32:37 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 14 Oct 2005 17:32:37 +0200 (CEST) Subject: [pypy-svn] r18563 - pypy/dist/pypy/rpython/llinterpreter Message-ID: <20051014153237.67D6927B58@code1.codespeak.net> Author: hpk Date: Fri Oct 14 17:32:37 2005 New Revision: 18563 Removed: pypy/dist/pypy/rpython/llinterpreter/ Log: remove an unused directory From boria at codespeak.net Fri Oct 14 17:34:46 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 17:34:46 +0200 (CEST) Subject: [pypy-svn] r18564 - pypy/branch/hl-backend/pypy/rpython Message-ID: <20051014153446.7F3F527B58@code1.codespeak.net> Author: boria Date: Fri Oct 14 17:34:46 2005 New Revision: 18564 Modified: pypy/branch/hl-backend/pypy/rpython/rmodel.py Log: * Put back this line to avoid breaking translator/c/. Modified: pypy/branch/hl-backend/pypy/rpython/rmodel.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rmodel.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rmodel.py Fri Oct 14 17:34:46 2005 @@ -309,6 +309,7 @@ # __________ utilities __________ from pypy.rpython.typesystem import LowLevelTypeSystem getfunctionptr = LowLevelTypeSystem.instance.getcallable +PyObjPtr = Ptr(PyObject) def needsgc(classdef, nogc=False): if classdef is None: From boria at codespeak.net Fri Oct 14 17:44:59 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 17:44:59 +0200 (CEST) Subject: [pypy-svn] r18565 - in pypy/branch/hl-backend/pypy: doc doc/image interpreter/pyparser/test module/Numeric module/_socket module/_socket/test objspace/flow objspace/flow/test objspace/std objspace/std/test rpython rpython/l3interp rpython/memory rpython/memory/test rpython/module rpython/test translator translator/asm translator/asm/i386gen translator/asm/ppc translator/asm/ppcgen translator/asm/test translator/c translator/c/src translator/c/test translator/goal translator/js translator/js/test translator/llvm translator/llvm/module Message-ID: <20051014154459.1674F27B57@code1.codespeak.net> Author: boria Date: Fri Oct 14 17:44:56 2005 New Revision: 18565 Added: pypy/branch/hl-backend/pypy/doc/image/JIT.dot - copied unchanged from r18564, pypy/dist/pypy/doc/image/JIT.dot pypy/branch/hl-backend/pypy/module/Numeric/ (props changed) - copied from r18564, pypy/dist/pypy/module/Numeric/ pypy/branch/hl-backend/pypy/module/_socket/ (props changed) - copied from r18564, pypy/dist/pypy/module/_socket/ pypy/branch/hl-backend/pypy/rpython/l3interp/ - copied from r18564, pypy/dist/pypy/rpython/l3interp/ pypy/branch/hl-backend/pypy/rpython/module/ll_stack.py - copied unchanged from r18564, pypy/dist/pypy/rpython/module/ll_stack.py pypy/branch/hl-backend/pypy/translator/asm/ppc/ - copied from r18564, pypy/dist/pypy/translator/asm/ppc/ pypy/branch/hl-backend/pypy/translator/asm/regalloc.py - copied unchanged from r18564, pypy/dist/pypy/translator/asm/regalloc.py pypy/branch/hl-backend/pypy/translator/asm/simulator.py - copied unchanged from r18564, pypy/dist/pypy/translator/asm/simulator.py pypy/branch/hl-backend/pypy/translator/asm/test/test_simulator.py - copied unchanged from r18564, pypy/dist/pypy/translator/asm/test/test_simulator.py pypy/branch/hl-backend/pypy/translator/c/src/stack.h - copied unchanged from r18564, pypy/dist/pypy/translator/c/src/stack.h pypy/branch/hl-backend/pypy/translator/goal/targetrpystonedalone.py - copied unchanged from r18564, pypy/dist/pypy/translator/goal/targetrpystonedalone.py Modified: pypy/branch/hl-backend/pypy/doc/draft-dynamic-language-translation.txt pypy/branch/hl-backend/pypy/doc/image/lattice1.dot pypy/branch/hl-backend/pypy/doc/news.txt pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astcompiler.py pypy/branch/hl-backend/pypy/module/_socket/test/ (props changed) pypy/branch/hl-backend/pypy/objspace/flow/model.py pypy/branch/hl-backend/pypy/objspace/flow/objspace.py pypy/branch/hl-backend/pypy/objspace/flow/test/test_objspace.py pypy/branch/hl-backend/pypy/objspace/std/longobject.py pypy/branch/hl-backend/pypy/objspace/std/test/test_longobject.py pypy/branch/hl-backend/pypy/rpython/extfunctable.py pypy/branch/hl-backend/pypy/rpython/llinterp.py pypy/branch/hl-backend/pypy/rpython/memory/gc.py pypy/branch/hl-backend/pypy/rpython/memory/lltypesimulation.py pypy/branch/hl-backend/pypy/rpython/memory/simulator.py pypy/branch/hl-backend/pypy/rpython/memory/test/test_gc.py pypy/branch/hl-backend/pypy/rpython/memory/test/test_lltypesimulation.py pypy/branch/hl-backend/pypy/rpython/module/ll_stackless.py pypy/branch/hl-backend/pypy/rpython/objectmodel.py pypy/branch/hl-backend/pypy/rpython/rint.py pypy/branch/hl-backend/pypy/rpython/rtyper.py pypy/branch/hl-backend/pypy/rpython/test/test_rint.py pypy/branch/hl-backend/pypy/rpython/test/test_rlist.py pypy/branch/hl-backend/pypy/rpython/test/test_rstr.py pypy/branch/hl-backend/pypy/translator/asm/genasm.py pypy/branch/hl-backend/pypy/translator/asm/i386gen/ (props changed) pypy/branch/hl-backend/pypy/translator/asm/infregmachine.py (contents, props changed) pypy/branch/hl-backend/pypy/translator/asm/ppcgen/func_builder.py pypy/branch/hl-backend/pypy/translator/asm/test/test_asm.py pypy/branch/hl-backend/pypy/translator/c/extfunc.py pypy/branch/hl-backend/pypy/translator/c/funcgen.py pypy/branch/hl-backend/pypy/translator/c/gc.py pypy/branch/hl-backend/pypy/translator/c/genc.py pypy/branch/hl-backend/pypy/translator/c/src/address.h pypy/branch/hl-backend/pypy/translator/c/src/g_include.h pypy/branch/hl-backend/pypy/translator/c/src/ll_stackless.h pypy/branch/hl-backend/pypy/translator/c/src/mem.h pypy/branch/hl-backend/pypy/translator/c/src/support.h pypy/branch/hl-backend/pypy/translator/c/stackless.py pypy/branch/hl-backend/pypy/translator/c/test/test_annotated.py pypy/branch/hl-backend/pypy/translator/c/test/test_extfunc.py pypy/branch/hl-backend/pypy/translator/c/test/test_lladdresses.py pypy/branch/hl-backend/pypy/translator/c/test/test_standalone.py pypy/branch/hl-backend/pypy/translator/c/test/test_typed.py pypy/branch/hl-backend/pypy/translator/goal/bench-windows.py pypy/branch/hl-backend/pypy/translator/goal/driver.py pypy/branch/hl-backend/pypy/translator/goal/targetnopstandalone.py pypy/branch/hl-backend/pypy/translator/goal/targetrichards.py pypy/branch/hl-backend/pypy/translator/goal/translate_pypy.py pypy/branch/hl-backend/pypy/translator/js/arraynode.py pypy/branch/hl-backend/pypy/translator/js/codewriter.py pypy/branch/hl-backend/pypy/translator/js/database.py pypy/branch/hl-backend/pypy/translator/js/funcnode.py pypy/branch/hl-backend/pypy/translator/js/js.py pypy/branch/hl-backend/pypy/translator/js/node.py pypy/branch/hl-backend/pypy/translator/js/opaquenode.py pypy/branch/hl-backend/pypy/translator/js/opwriter.py pypy/branch/hl-backend/pypy/translator/js/structnode.py pypy/branch/hl-backend/pypy/translator/js/test/test_genllvm1.py pypy/branch/hl-backend/pypy/translator/llvm/build_llvm_module.py pypy/branch/hl-backend/pypy/translator/llvm/externs2ll.py pypy/branch/hl-backend/pypy/translator/llvm/gc.py pypy/branch/hl-backend/pypy/translator/llvm/module/genexterns.c pypy/branch/hl-backend/pypy/translator/transform.py pypy/branch/hl-backend/pypy/translator/translator.py Log: * Merged trunk (dist/pypy/) at revision 18564 into hl-backend branch. Modified: pypy/branch/hl-backend/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/branch/hl-backend/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/branch/hl-backend/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 14 17:44:56 2005 @@ -783,8 +783,8 @@ - *b*, *b'*, *b''*... are maps from *V* to *A*. We call *state* a pair *(b,E)*. We say that a state *(b',E')* is more -general than a state *(b,E)* if for all variables *v* we have *b'(v) >= -b(v)* and *E'* includes at least all relations of *E*. There is: +general than a state *(b,E)* if for all variables *v* we have ``b'(v) >= +b(v)`` and *E'* includes at least all relations of *E*. There is: - a most general state, with *bmax(v) = Top* for all *v* and *Emax* identifying all variables with each other; @@ -854,15 +854,15 @@ .. _merge_into: In the sequel, a lot of rules will be based on the following -``merge_into`` operator. Given two variables *x* and *y*, -``merge_into(x,y)`` modifies the state as follows:: +``merge_into`` operator. Given an annotation *a* and a variable *x*, +``merge_into(a,x)`` modifies the state as follows:: - merge_into(x,y): - if b(x)=List(v) and b(y)=List(w): + merge_into(a,x): + if a=List(v) and b(x)=List(w): b' = b - E' = E union (v~w) + E' = E union (v ~ w) else: - b' = b with (y -> b(x) \/ b(y)) + b' = b with (x -> a \/ b(x)) E' = E where ``\/`` is the union in the lattice *A*. @@ -875,7 +875,7 @@ y = phi(x) ---------------------------------------- - merge_into(x,y) + merge_into(b(x),y) The purpose of the equivalence relation *E* is to force two identified variables to keep the same binding. The rationale for this is explained @@ -884,13 +884,13 @@ (x~y) in E ---------------------------------------- - merge_into(x,y) - merge_into(y,x) + merge_into(b(x),y) + merge_into(b(y),x) -Note that in theory, all rules should be tried repeatedly until none of +Note that a priori, all rules should be tried repeatedly until none of them generalizes the state any more, at which point we have reached a -fixpoint. In practice, the rules are well suited to a simple metarule -that tracks a small set of rules that can possibly apply. Only these +fixpoint. However, the rules are well suited to a simple metarule that +tracks a small set of rules that can possibly apply. Only these "scheduled" rules are tried. The metarule is as follows: - when an identification *x~y* is added to *E*, then the rule @@ -966,7 +966,7 @@ setitem(x,y,z), b(x)=List(v) -------------------------------------------- - merge_into(z,v) + merge_into(b(z),v) Reading an item out a list requires care to ensure that the rule is rescheduled if the binding of the hidden variable is generalized. We do @@ -1019,9 +1019,9 @@ instances". By default, instances of some user-defined class that happens to pre-exist annotation have no constantness requirement on their own; after annotation and possibly compilation, these instances -will continue to behave as regular mutable instances of that class. -These prebuilt instances are decribed in another section (`Constant -annotations`_). However, the user program can give a hint that forces +will continue to behave as regular mutable instances of that class, +turned into mostly regular ``Inst(C)`` annotations when the annotator +encounters them. However, the user program can give a hint that forces the annotator to consider the object as a "frozen prebuilt constant". The object is then considered as a now-immutable container of attributes. It looses its object-oriented aspects and its class becomes @@ -1071,15 +1071,15 @@ program that is static enough, it must reconstruct a static structure for each class in the hierarchy. It does so by observing the usage patterns of the classes and their instances, by propagating annotations -of the form ``SomeInstance(cls)`` -- which stands for "an instance of -the class *cls* or any subclass". Instance fields are attached to a -class whenever we see that the field is being written to an instance of -this class. If the user program manipulates instances polymorphically, -the variables holding the instances will be annotated -``SomeInstance(cls)`` with some abstract base class *cls*; accessing -attributes on such generalized instances lifts the inferred attribute -declarations up to *cls*. The same technique works for inferring the -location of both fields and methods. +of the form ``Inst(cls)`` -- which stands for "an instance of the class +*cls* or any subclass". Instance fields are attached to a class +whenever we see that the field is being written to an instance of this +class. If the user program manipulates instances polymorphically, the +variables holding the instances will be annotated ``Inst(cls)`` with +some abstract base class *cls*; accessing attributes on such generalized +instances lifts the inferred attribute declarations up to *cls*. The +same technique works for inferring the location of both fields and +methods. ~~~~~~~~~~~~~~~~~~~~~~ @@ -1119,135 +1119,139 @@ setattr(x,attr,z), b(x)=Inst(C) --------------------------------------------------------------------- E' = E union (v_C.attr ~ v_D.attr) for all D subclass of C - merge_into(z, v_C.attr) - -The purpose of ``lookup_filter`` is to avoid loosing precision in method -calls. Indeed, as described more precisely in `Constant annotations`_ -below, if ``attr`` names a method of the class ``C`` then the binding -``b(v_C.attr)`` is a ``Pbc`` that includes all the "potental bound -method" objects ``D.f``, for each subclass ``D`` of ``C`` where a -function ``f`` is present under the name ``attr``. - -XXX - - -if ``attr`` is a method defined on XXX:: - - lookup_filter(Pbc(set), class) = Pbc(newset) where - we only keep in newset the non-methods, and the following methods: - * the ones bound to a strict subclass of 'class', and - * among the methods bound the 'class' or superclasses, only the - one from the most derived class. - lookup_filter(NonPbcAnnotation, class) = NonPbcAnnotation + merge_into(b(z), v_C.attr) Note the similarity with the ``getitem`` and ``setitem`` of lists, in particular the usage of the auxiliary variable *z'*. -XXX - +The purpose of ``lookup_filter`` is to avoid loosing precision in method +calls. Indeed, if ``attr`` names a method of the class ``C`` then the +binding ``b(v_C.attr)`` is initialized to ``Pbc(m)``, where *m* is the +following set: -Constant annotations -~~~~~~~~~~~~~~~~~~~~ +* for each subclass ``D`` of ``C``, if the class ``D`` introduces a method + ``attr`` implemented as, say, the function ``f``, then the "potential + bound method" object ``D.f`` belongs to *m*. -XXX constant arguments to operations +However, because of the possible identification between the variable +``v_C.attr`` and the corresponding variable ``v_B.attr`` of a +superclass, the set *m* might end up containing potential bound methods +of other unrelated subclasses of ``B``, even when performing a +``getattr`` on what we know is an instance of ``C``. The +``lookup_filter`` reverses this effect as follows:: + lookup_filter(Pbc(set), C) = Pbc(newset) + lookup_filter(NonPbcAnnotation, C) = NonPbcAnnotation -Draft -~~~~~ +where the *newset* only keeps the non-methods of *set* (if any) plus the +following methods: -:: +* the ones bound to a strict subclass of ``C``, plus - Char - - Inst(class) - - List(x) - - Dict(x, y) - - Tup(ann_1, ..., ann_n) - - Pbc({... a finite set ...}) - - with: None - f - class - class.f - - v_n = op(v_n1, ...) | v_n', v_n'' - - v_class.attr - - v_n: Annotation - - for each function f: - arg_f_1 ... arg_f_n - returnvar_f - - - E: eq rel on V - b: V->A - V: set of variables - A: fixed lattice of the above annotation terms +* among the methods bound to ``C`` or superclasses of ``C``, only the + one from the most derived class. - z=getattr(x,attr) | z', b(x)=Inst(A) - --------------------------------------------------------------------- - E' = E union (A.attr ~ A'.attr) for all A' subclass of A - E' = E union (z' ~ A.attr) - b' = b with (z->lookup_filter(b(z'), A)) - - - setattr(x,attr,z), b(x)=Inst(A) - --------------------------------------------------------------------- - assert b(z) is not a Pbc containing methods - E' = E union (A.attr ~ A'.attr) for all A' subclass of A - merge_into(z, A.attr) +Calls +~~~~~ +The ``Pbc`` annotations regroup (among others) all user-defined callable +objects: functions, methods and classes. A call in the user program +turns into a ``simplecall`` operation whose first argument is the object +to call. Here is the corresponding rule -- regrouping all cases because +the same ``Pbc(set)`` could mix several kinds of callables:: z=simplecall(x,y1,...,yn), b(x)=Pbc(set) --------------------------------------------------------------------- for each c in set: if c is a function: - E' = E union (z~returnvar_c) - merge_into(y1, arg_c_1) + E' = E union (z ~ returnvar_c) + merge_into(b(y1), arg_c_1) ... - merge_into(yn, arg_c_n) + merge_into(b(yn), arg_c_n) if c is a class: let f = c.__init__ - b' = b with (z->b(z)\/Inst(c)) - b' = b with (arg_f_1->b(arg_f_1)\/Inst(c)) - merge_into(y1, arg_f_2) + merge_into(Inst(c), z) + merge_into(Inst(c), arg_f_1) + merge_into(b(y1), arg_f_2) ... - merge_into(yn, arg_f_(n+1)) + merge_into(b(yn), arg_f_(n+1)) if c is a method: let class.f = c - E' = E union (z~returnvar_f) - b' = b with (arg_f_1->b(arg_f_1)\/Inst(class)) - merge_into(y1, arg_f_2) + E' = E union (z ~ returnvar_f) + merge_into(Inst(class), arg_f_1) + merge_into(b(y1), arg_f_2) ... - merge_into(yn, arg_f_(n+1)) + merge_into(b(yn), arg_f_(n+1)) + +Calling a class returns an instance and flows the annotations into the +contructor ``__init__`` of the class. Calling a method inserts the +instance annotation as the first argument of the underlying function +(the annotation is exactly ``Inst(C)`` for the class ``C`` in which the +method is found). - lookup_filter(Pbc(set), class) = Pbc(newset) where - we only keep in newset the non-methods, and the following methods: - * the ones bound to a strict subclass of 'class', and - * among the methods bound the 'class' or superclasses, only the - one from the most derived class. - lookup_filter(NonPbcAnnotation, class) = NonPbcAnnotation +Termination and soundness +~~~~~~~~~~~~~~~~~~~~~~~~~ +As the annotation process is a fix-point search, it is necessary for +completeness to prove more formally that it is well-behaved. The +following proofs are all rather easy given the approach we have taken. Termination -~~~~~~~~~~~ +*********** + +We first have to check that each rule can only turn a state *(b,E)* into +a state *(b',E')* that is either identical or more general. To do so, +we first verify that they all have the following properties: + +* if *z* is the result variable of an operation, the binding ``b(z)`` is + only ever modified by the rule (or rules) about this operation: this + is true because *E* never identifies such a result variable with any + other variable. + +* the annotation ``b(z)`` of such a result variable can only become more + general: using the previous point, this can be checked on the rule (or + rules) of each operation independently. Indeed, there are only two + ways in which ``b(z)`` is modified: by ``merge_into(..., z)``, which + trivially guarantees the property by being based on the union operator + ``\/`` of the lattice, or explicitely in a way that can easily be + checked to respect the property. + +... + + +Each basic step (execution of one rule) can lead to the generalization +of the state. If it does, then other rules may be scheduled or +re-scheduled for execution. The state can only be generalized a finite +number of times because both the lattice *A* and the set of variables +*V* of which *E* is an equivalence relation are finite. If a rule does +not lead to any generalization, then it does not trigger re-scheduling +of any other rule. This ensures that the process eventually terminates. + +The extended lattice used in practice is a priori not finite. As we did +not describe this lattice formally here, we have to skip the (easy) +proof that it still contains no infinite ascending chain. An ascending +chain is a sequence where each item is strictly larger than the previous +one. + +Soundness +********* + +We define an annotation state to be *sound* if none of the rules would +lead to further Xxx. + XXX termination + soundness + most-precise-fixpoint-ness + complexity +Complexity +********** + The lattice is finite, although its size depends on the size of the program. The List part has the same size as *V*, and the Pbc part is exponential on the number of prebuilt constants. However, in this model -a chain of annotations (where each one is larger than the previous) -cannot be longer than:: +a chain of annotations cannot be longer than:: max(5, number-of-pbcs + 3, depth-of-class-hierarchy + 3). @@ -1258,6 +1262,9 @@ to prove that there is no infinite ascending chain, which is enough to guarantee termination. +Additionally, an important property of ``lookup_filter`` is to be +monotonic: XXX + Non-static aspects ~~~~~~~~~~~~~~~~~~ Modified: pypy/branch/hl-backend/pypy/doc/image/lattice1.dot ============================================================================== --- pypy/branch/hl-backend/pypy/doc/image/lattice1.dot (original) +++ pypy/branch/hl-backend/pypy/doc/image/lattice1.dot Fri Oct 14 17:44:56 2005 @@ -4,11 +4,11 @@ Top -> "*instances*" -> Bottom; "*instances*" -> None; NullableStr -> None; - Top -> "*callables*" -> Bottom; - "*callables*" -> None; + Top -> "*PBCs*" -> Bottom; + "*PBCs*" -> None; Top -> "*lists*" -> None -> Bottom; "*lists*" [shape=box]; "*instances*" [shape=box]; - "*callables*" [shape=box]; + "*PBCs*" [shape=box]; } Modified: pypy/branch/hl-backend/pypy/doc/news.txt ============================================================================== --- pypy/branch/hl-backend/pypy/doc/news.txt (original) +++ pypy/branch/hl-backend/pypy/doc/news.txt Fri Oct 14 17:44:56 2005 @@ -18,12 +18,13 @@ `continuation-passing`_ style (stackless), making the translation process work for target languages with more powerful object systems and some tiny steps into the JIT_ direction. Michael and Carl have written -a `report about day one`_. *(10/11/2005)* +a `report about day one`_ and `one about day two and three`_. *(10/14/2005)* .. _`Logilabs offices in Paris`: http://codespeak.net/pypy/extradoc/sprintinfo/paris-2005-sprint.html .. _JIT: http://en.wikipedia.org/wiki/Just-in-time_compilation .. _`continuation-passing`: http://en.wikipedia.org/wiki/Continuation_passing_style .. _`report about day one`: http://codespeak.net/pipermail/pypy-dev/2005q4/002510.html +.. _`one about day two and three`: http://codespeak.net/pipermail/pypy-dev/2005q4/002512.html PyPy release 0.7.0 =================== Modified: pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astbuilder.py ============================================================================== --- pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astbuilder.py (original) +++ pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astbuilder.py Fri Oct 14 17:44:56 2005 @@ -715,10 +715,8 @@ 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' + source = file(filepath).read() + yield check_expression, source, 'exec' def test_eval_string(): Modified: pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astcompiler.py ============================================================================== --- pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astcompiler.py (original) +++ pypy/branch/hl-backend/pypy/interpreter/pyparser/test/test_astcompiler.py Fri Oct 14 17:44:56 2005 @@ -204,6 +204,19 @@ source = file(filepath).read() yield check_compile, source, 'exec' +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 not basename.endswith('.py'): + continue + filepath = os.path.join(STDLIB_PATH, basename) + # size = os.stat(filepath)[6] + # filter on size + # if size <= 10000: + source = file(filepath).read() + yield check_compile, source, 'exec' + def test_libstuff(): for snippet_name in LIBSTUFF: filepath = os.path.join(os.path.dirname(__file__), '../../../lib', snippet_name) Modified: pypy/branch/hl-backend/pypy/objspace/flow/model.py ============================================================================== --- pypy/branch/hl-backend/pypy/objspace/flow/model.py (original) +++ pypy/branch/hl-backend/pypy/objspace/flow/model.py Fri Oct 14 17:44:56 2005 @@ -256,6 +256,7 @@ name = '_' + name name = self.namesdict.setdefault(name, (name, 0))[0] self._name = name + self._nr = -1 def set_name_from(self, v): # this is for SSI_to_SSA only which should not know about internals Modified: pypy/branch/hl-backend/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/branch/hl-backend/pypy/objspace/flow/objspace.py (original) +++ pypy/branch/hl-backend/pypy/objspace/flow/objspace.py Fri Oct 14 17:44:56 2005 @@ -395,7 +395,7 @@ types.ClassType, types.TypeType)) and c.__module__ in ['__builtin__', 'exceptions']): - exceptions = None + exceptions = implicit_exceptions.get(c, None) self.handle_implicit_exceptions(exceptions) return w_res @@ -434,7 +434,9 @@ op_appendices[_exc] = _name del _name, _exc -implicit_exceptions = {} +implicit_exceptions = { + int: [ValueError], # built-ins that can always raise exceptions + } def _add_exceptions(names, exc): for name in names.split(): Modified: pypy/branch/hl-backend/pypy/objspace/flow/test/test_objspace.py ============================================================================== --- pypy/branch/hl-backend/pypy/objspace/flow/test/test_objspace.py (original) +++ pypy/branch/hl-backend/pypy/objspace/flow/test/test_objspace.py Fri Oct 14 17:44:56 2005 @@ -267,7 +267,7 @@ def implicitException_int_and_id(x): try: return int(x) + id(x) - except ValueError: # not captured by the flow graph! + except TypeError: # not captured by the flow graph! return 0 def test_implicitException_int_and_id(self): Modified: pypy/branch/hl-backend/pypy/objspace/std/longobject.py ============================================================================== --- pypy/branch/hl-backend/pypy/objspace/std/longobject.py (original) +++ pypy/branch/hl-backend/pypy/objspace/std/longobject.py Fri Oct 14 17:44:56 2005 @@ -99,10 +99,10 @@ def fromint(space, intval): if intval < 0: sign = -1 - ival = -intval + ival = r_uint(-intval) elif intval > 0: sign = 1 - ival = intval + ival = r_uint(intval) else: return W_LongObject(space, [0], 0) # Count the number of Python digits. @@ -118,7 +118,7 @@ t = ival p = 0 while t: - v.digits[p] = t & MASK + v.digits[p] = intmask(t & MASK) t >>= SHIFT p += 1 return v Modified: pypy/branch/hl-backend/pypy/objspace/std/test/test_longobject.py ============================================================================== --- pypy/branch/hl-backend/pypy/objspace/std/test/test_longobject.py (original) +++ pypy/branch/hl-backend/pypy/objspace/std/test/test_longobject.py Fri Oct 14 17:44:56 2005 @@ -409,3 +409,9 @@ raises(ValueError, math.log, 0) raises(ValueError, math.log, -1) raises(ValueError, math.log, -2) + + def test_long(self): + import sys + n = -sys.maxint-1 + assert long(n) == n + assert str(long(n)) == str(n) Modified: pypy/branch/hl-backend/pypy/rpython/extfunctable.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/extfunctable.py (original) +++ pypy/branch/hl-backend/pypy/rpython/extfunctable.py Fri Oct 14 17:44:56 2005 @@ -209,6 +209,9 @@ # stackless from pypy.rpython import objectmodel declare(objectmodel.stack_frames_depth, int, 'll_stackless/stack_frames_depth') +declare(objectmodel.stack_too_big, bool, 'll_stack/too_big') +declare(objectmodel.stack_check, noneannotation, 'll_stack/check') +declare(objectmodel.stack_unwind, noneannotation, 'll_stack/unwind') # ___________________________________________________________ # the exceptions that can be implicitely raised by some operations @@ -224,4 +227,5 @@ KeyError : True, IndexError : True, AssertionError : True, + RuntimeError : True, } Modified: pypy/branch/hl-backend/pypy/rpython/llinterp.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/llinterp.py (original) +++ pypy/branch/hl-backend/pypy/rpython/llinterp.py Fri Oct 14 17:44:56 2005 @@ -324,7 +324,10 @@ result = self.op_direct_call(malloc, *args) return self.llinterpreter.gc.adjust_result_malloc(result, obj, size) else: - return self.llt.malloc(obj, size) + try: + return self.llt.malloc(obj, size) + except MemoryError, e: + self.make_llexception(e) def op_flavored_malloc(self, flavor, obj): assert isinstance(flavor, str) Modified: pypy/branch/hl-backend/pypy/rpython/memory/gc.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/memory/gc.py (original) +++ pypy/branch/hl-backend/pypy/rpython/memory/gc.py Fri Oct 14 17:44:56 2005 @@ -34,12 +34,14 @@ ll = AddressLinkedList() ll.append(NULL) ll.append(raw_malloc(10)) + ll.pop() #make the annotator see pop return ll def dummy_get_roots2(): ll = AddressLinkedList() ll.append(raw_malloc(10)) ll.append(NULL) + ll.pop() #make the annotator see pop return ll @@ -67,6 +69,30 @@ "NOT_RPYTHON" pass +class DummyGC(GCBase): + _alloc_flavor_ = "raw" + + def __init__(self, dummy=None, get_roots=None): + self.get_roots = get_roots + self.set_query_functions(None, None, None, None, None, None, None) + + def malloc(self, typeid, length=0): + size = self.fixed_size(typeid) + if self.is_varsize(typeid): + size += length * self.varsize_item_sizes(typeid) + return raw_malloc(size) + + def collect(self): + self.get_roots() #this is there so that the annotator thinks get_roots is a function + + def size_gc_header(self, typeid=0): + return 0 + + def init_gc_object(self, addr, typeid): + return + init_gc_object_immortal = init_gc_object + + class MarkSweepGC(GCBase): _alloc_flavor_ = "raw" Modified: pypy/branch/hl-backend/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/branch/hl-backend/pypy/rpython/memory/lltypesimulation.py Fri Oct 14 17:44:56 2005 @@ -48,7 +48,7 @@ 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): + if self._T._arrayfld is not None: addr = self._address + self._layout[self._T._arrayfld] addr.signed[0] = size else: Modified: pypy/branch/hl-backend/pypy/rpython/memory/simulator.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/memory/simulator.py (original) +++ pypy/branch/hl-backend/pypy/rpython/memory/simulator.py Fri Oct 14 17:44:56 2005 @@ -113,7 +113,8 @@ return self.blocks[mid] def malloc(self, size): - assert size > 0 + if size == 0: + size = 1 result = self.freememoryaddress self.blocks.append(MemoryBlock(result, size)) self.freememoryaddress += size Modified: pypy/branch/hl-backend/pypy/rpython/memory/test/test_gc.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/memory/test/test_gc.py (original) +++ pypy/branch/hl-backend/pypy/rpython/memory/test/test_gc.py Fri Oct 14 17:44:56 2005 @@ -5,7 +5,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.gc import DeferredRefcountingGC, DummyGC 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 @@ -138,3 +138,22 @@ def teardown_class(cls): gclltype.prepare_graphs_and_create_gc = cls.prep_old.im_func gclltype.use_gc = cls.old + +class TestDummyGC(TestMarkSweepGC): + def setup_class(cls): + gclltype.use_gc = DummyGC + cls.old = gclltype.use_gc + def teardown_class(cls): + gclltype.use_gc = cls.old + +class TestDummyGCRunningOnLLinterp(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 = DummyGC + 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 + Modified: pypy/branch/hl-backend/pypy/rpython/memory/test/test_lltypesimulation.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/memory/test/test_lltypesimulation.py (original) +++ pypy/branch/hl-backend/pypy/rpython/memory/test/test_lltypesimulation.py Fri Oct 14 17:44:56 2005 @@ -121,6 +121,11 @@ assert s1.a == 17 assert s1.rest[3].v == 5 +def test_empty_struct(): + S1 = lltype.GcStruct("s1") + s1 = malloc(S1) + assert s1 == s1 + def test_substructure_ptr(): S3 = lltype.Struct("s3", ('a', lltype.Signed)) S2 = lltype.Struct("s2", ('s3', S3), ('char', lltype.Char)) Modified: pypy/branch/hl-backend/pypy/rpython/module/ll_stackless.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/module/ll_stackless.py (original) +++ pypy/branch/hl-backend/pypy/rpython/module/ll_stackless.py Fri Oct 14 17:44:56 2005 @@ -1,6 +1,5 @@ from pypy.rpython import objectmodel - def ll_stackless_stack_frames_depth(): return objectmodel.stack_frames_depth() ll_stackless_stack_frames_depth.suggested_primitive = True Modified: pypy/branch/hl-backend/pypy/rpython/objectmodel.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/objectmodel.py (original) +++ pypy/branch/hl-backend/pypy/rpython/objectmodel.py Fri Oct 14 17:44:56 2005 @@ -38,9 +38,22 @@ def hlinvoke(repr, llcallable, *args): raise TypeError, "hlinvoke is meant to be rtyped and not called direclty" +def stack_unwind(): + pass + def stack_frames_depth(): return len(inspect.stack()) +def stack_too_big(): + return False + +def stack_check(): + if stack_too_big(): + # stack_unwind implementation is different depending on if stackless + # is enabled. If it is it unwinds the stack, otherwise it simply + # raises a RuntimeError. + stack_unwind() + # ____________________________________________________________ Modified: pypy/branch/hl-backend/pypy/rpython/rint.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rint.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rint.py Fri Oct 14 17:44:56 2005 @@ -295,7 +295,9 @@ sign = 0 if i < 0: sign = 1 - i = -i + i = r_uint(-i) + else: + i = r_uint(i) if i == 0: len = 1 temp[0] = '0' Modified: pypy/branch/hl-backend/pypy/rpython/rtyper.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/rtyper.py (original) +++ pypy/branch/hl-backend/pypy/rpython/rtyper.py Fri Oct 14 17:44:56 2005 @@ -25,6 +25,7 @@ from pypy.rpython.ootypesystem import ootype from pypy.tool.sourcetools import func_with_new_name, valid_identifier from pypy.translator.unsimplify import insert_empty_block +from pypy.translator.transform import insert_stackcheck from pypy.rpython.rmodel import Repr, inputconst from pypy.rpython.rmodel import TyperError, BrokenReprTyperError from pypy.rpython.rmodel import warning @@ -139,8 +140,10 @@ """Main entry point: specialize all annotated blocks of the program.""" self.crash_on_first_typeerror = crash_on_first_typeerror # specialize depends on annotator simplifications + insert_stackcheck(self.annotator) if not dont_simplify_again: self.annotator.simplify() + # first make sure that all functions called in a group have exactly # the same signature, by hacking their flow graphs if needed perform_normalizations(self) Modified: pypy/branch/hl-backend/pypy/rpython/test/test_rint.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/test/test_rint.py (original) +++ pypy/branch/hl-backend/pypy/rpython/test/test_rint.py Fri Oct 14 17:44:56 2005 @@ -1,3 +1,4 @@ +import sys from pypy.translator.translator import Translator from pypy.rpython.rtyper import RPythonTyper from pypy.annotation import model as annmodel @@ -62,7 +63,10 @@ res = interpret(dummy, [-123]) assert ''.join(res.chars) == '-123' - + + res = interpret(dummy, [-sys.maxint-1]) + assert ''.join(res.chars) == str(-sys.maxint-1) + def test_hex_of_int(): def dummy(i): return hex(i) Modified: pypy/branch/hl-backend/pypy/rpython/test/test_rlist.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/test/test_rlist.py (original) +++ pypy/branch/hl-backend/pypy/rpython/test/test_rlist.py Fri Oct 14 17:44:56 2005 @@ -1,3 +1,4 @@ +import sys from pypy.translator.translator import Translator from pypy.rpython.lltype import * from pypy.rpython.rtyper import RPythonTyper @@ -500,3 +501,14 @@ assert res == 2 res = interpret(fn, [6]) assert res == 100 + +def test_memoryerror(): + def fn(i): + lst = [0] * i + lst[i-1] = 5 + return lst[0] + res = interpret(fn, [1]) + assert res == 5 + res = interpret(fn, [2]) + assert res == 0 + interpret_raises(MemoryError, fn, [sys.maxint]) Modified: pypy/branch/hl-backend/pypy/rpython/test/test_rstr.py ============================================================================== --- pypy/branch/hl-backend/pypy/rpython/test/test_rstr.py (original) +++ pypy/branch/hl-backend/pypy/rpython/test/test_rstr.py Fri Oct 14 17:44:56 2005 @@ -472,6 +472,17 @@ res = interpret(fn, [i, j]) assert res == expected +def test_int_valueerror(): + s1 = ['42g', '?'] + def fn(i): + try: + return int(s1[i]) + except ValueError: + return -654 + res = interpret(fn, [0]) + assert res == -654 + res = interpret(fn, [1]) + assert res == -654 def test_char_mul_n(): def f(c, n): Modified: pypy/branch/hl-backend/pypy/translator/asm/genasm.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/asm/genasm.py (original) +++ pypy/branch/hl-backend/pypy/translator/asm/genasm.py Fri Oct 14 17:44:56 2005 @@ -2,6 +2,7 @@ from pypy.objspace.flow.model import traverse, Block, Variable, Constant from pypy.translator.asm import infregmachine from pypy.rpython.lltype import Signed +from pypy.translator.asm.simulator import Machine, TranslateProgram #Available Machine code targets (processor+operating system) TARGET_UNKNOWN=0 @@ -33,7 +34,7 @@ from pypy.translator.asm.i386gen.i386_assembler import make_func -def genasm(translator): +def genasm(translator, processor): f = translator.entrypoint @@ -48,10 +49,27 @@ g = FuncGenerator(graph) g.gencode() -# g.assembler.dump() - finreg = g.assembler.allocate_registers(30) - return make_func(finreg.assemble(), 'i', 'i'*len(graph.startblock.inputargs)) + if processor == 'virt': + def r(*args): + return Machine.RunProgram(g.assembler.instructions, + args, + tracing=True) + + return r + elif processor == 'virtfinite': + insns = TranslateProgram(g.assembler.instructions, 50) + for i in insns: + print i + def r(*args): + return Machine.RunProgram(insns, + args, + tracing=True) + + return r + elif processor == 'ppc': + from pypy.translator.asm.ppc import codegen + return codegen.make_native_code(graph, g.assembler.instructions) class FuncGenerator(object): @@ -71,7 +89,7 @@ self.assembler = infregmachine.Assembler() for i, var in enumerate(graph.startblock.inputargs): - self.emit('LIA', self.reg(var), i) + self.emit('LIA', self.reg(var), Constant(i)) def assign_register(self, var): assert var not in self._var2reg @@ -85,7 +103,7 @@ if isinstance(var, Constant): r = self.next_register assert isinstance(var.value, int) - self.assembler.emit("LOAD", r, var.value) + self.assembler.emit("LOAD", r, var) self.next_register += 1 return r elif isinstance(var, Variable): @@ -128,7 +146,8 @@ assert block.exitswitch is not None falselink, truelink = block.exits lastop = block.operations[-1] - assert lastop.opname in ['int_gt', 'int_lt', 'int_ge'] + assert lastop.opname in ['int_gt', 'int_lt', 'int_ge', + 'int_eq', 'int_le', 'int_ne'] A.emit(lastop.opname, *map(self.reg, lastop.args)) b = self.blockname() A.emit('JT', b) Modified: pypy/branch/hl-backend/pypy/translator/asm/infregmachine.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/asm/infregmachine.py (original) +++ pypy/branch/hl-backend/pypy/translator/asm/infregmachine.py Fri Oct 14 17:44:56 2005 @@ -6,12 +6,15 @@ self.arguments = arguments def registers_used(self): - if self.name == 'LIA' or self.name == 'LOAD': - return [self.arguments[0]] - elif self.name in ('JT', 'JF', 'J'): - return [] - else: - return list(self.arguments) + return [a for a in self.arguments if isinstance(a, int)] + + def renumber(self, regmap): + def _(a): + if isinstance(a, int) and a in regmap: + return regmap[a] + else: + return a + return Instruction(self.name, map(_, self.arguments)) def __repr__(self): if self.name == 'LIA': @@ -20,10 +23,28 @@ elif self.name in ('JT', 'JF', 'J'): args = self.arguments[0] elif self.name == 'LOAD': - args = 'r%s, %s'%tuple(self.arguments) + args = 'r%s, #%s'%tuple(self.arguments) else: - args = ', '.join(['r%s'%a for a in self.arguments]) - return ' %-10s %s'%(self.name, args) + def c(x): + if isinstance(x, int): + return 'r%s'%x + else: + return str(x) + args = ', '.join(map(c, self.arguments)) + return '%-30s'%(' %-10s %s'%(self.name, args),) + +class Program(object): + # approximately a list of Instructions, but with sprinkles + # not used yet. + + def __init__(self, insns): + self.insns = insns + + def iterinsns(self): + for insn in self.insns: + if isinstance(ins, str): + continue + yield insn class Assembler(object): def __init__(self): @@ -40,67 +61,3 @@ if isinstance(i, str): i += ':' print i - - def allocate_registers(self, nregisters): - r = FiniteRegisterAssembler(nregisters) - for i in self.instructions: - if not isinstance(i, str): # labels - assert max(i.registers_used() + [0]) < nregisters - r.instructions.append(i) - return r - -class FiniteRegisterAssembler(Assembler): - def __init__(self, nregisters): - Assembler.__init__(self) - self.nregisters = nregisters - - def assemble(self): - from pypy.translator.asm.ppcgen import ppc_assembler - A = ppc_assembler.PPCAssembler() - - for i in self.instructions: - if isinstance(i, str): - A.label(i) - continue - - getattr(self, i.name)(A, *i.arguments) - - return A - - def LIA(self, A, dest, argindex): - assert dest + 2 == argindex + 3 - - def LOAD(self, A, dest, value): - assert isinstance(value, int) - assert -30000 < value < 30000 - A.li(dest + 2, value) - - def int_add(self, A, dest, a, b): - A.add(dest + 2, a + 2, b + 2) - - def int_sub(self, A, dest, a, b): - A.sub(dest + 2, a + 2, b + 2) - - def int_mul(self, A, dest, a, b): - A.mullw(dest + 2, a + 2, b + 2) - - def int_gt(self, A, a, b): - A.cmpw(a + 2, b + 2) - A.crmove(0, 1) - - def int_lt(self, A, a, b): - A.cmpw(a + 2, b + 2) - - def JT(self, A, branch): - # should be "A.bt(BI=0, BD=branch)" but this crashes. - A.blt(branch) - - def J(self, A, branch): - A.b(branch) - - def RETPYTHON(self, A, reg): - A.mr(3, reg + 2) - A.blr() - - def MOV(self, A, dest, src): - A.mr(dest + 2, src + 2) Modified: pypy/branch/hl-backend/pypy/translator/asm/ppcgen/func_builder.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/asm/ppcgen/func_builder.py (original) +++ pypy/branch/hl-backend/pypy/translator/asm/ppcgen/func_builder.py Fri Oct 14 17:44:56 2005 @@ -7,14 +7,14 @@ code.lwz(rD, r4, 12 + 4*argi) if typecode == 'i': code.load_word(r0, lookup("PyInt_Type")) - code.lwz(r15, rD, 4) # XXX ick! - code.cmpw(r0, r15) + code.lwz(r31, rD, 4) # XXX ick! + code.cmpw(r0, r31) code.bne("argserror") code.lwz(rD, rD, 8) elif typecode == 'f': code.load_word(r0, lookup("PyFloat_Type")) - code.lwz(r15, rD, 4) - code.cmpw(r0, r15) + code.lwz(r31, rD, 4) + code.cmpw(r0, r31) code.bne("argserror") code.lfd(rD-2, rD, 8) elif typecode != "O": @@ -22,16 +22,18 @@ FAST_ENTRY_LABEL = "FAST-ENTRY-LABEL" -def make_func(code, retcode, signature): +def make_func(code, retcode, signature, localwords=0): """code shouldn't contain prologue/epilogue (or touch r31)""" + stacksize = 80 + 4*localwords + argcount = len(signature) ourcode = MyPPCAssembler() ourcode.mflr(r0) ourcode.stmw(r31, r1, -4) ourcode.stw(r0, r1, 8) - ourcode.stwu(r1, r1, -80) + ourcode.stwu(r1, r1, -stacksize) ourcode.lwz(r3, r4, 8) ourcode.cmpwi(r3, argcount) @@ -47,7 +49,7 @@ load_arg(ourcode, 1, signature[1]) ourcode.bl(FAST_ENTRY_LABEL) - + if retcode == 'i': s = lookup("PyInt_FromLong") ourcode.load_word(r0, s) @@ -60,8 +62,8 @@ ourcode.bctrl() ourcode.label("epilogue") - ourcode.lwz(r0, r1, 88) - ourcode.addi(r1, r1, 80) + ourcode.lwz(r0, r1, stacksize + 8) + ourcode.addi(r1, r1, stacksize) ourcode.mtlr(r0) ourcode.lmw(r31, r1, -4) ourcode.blr() @@ -96,7 +98,7 @@ return r def wrap(funcname, retcode, signature): - + argcount = len(signature) ourcode = MyPPCAssembler() @@ -118,11 +120,11 @@ if argcount > 1: load_arg(ourcode, 1, signature[1]) - + ourcode.load_word(r0, lookup(funcname)) ourcode.mtctr(r0) ourcode.bctrl() - + if retcode == 'i': s = lookup("PyInt_FromLong") ourcode.load_word(r0, s) Modified: pypy/branch/hl-backend/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/asm/test/test_asm.py (original) +++ pypy/branch/hl-backend/pypy/translator/asm/test/test_asm.py Fri Oct 14 17:44:56 2005 @@ -1,14 +1,11 @@ from pypy.translator.translator import Translator +from pypy.rpython.rarithmetic import ovfcheck import py import os class TestAsm(object): - def setup_class(cls): - if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': - py.test.skip('asm generation only on PPC') - - cls.processor = 'ppc' + processor = 'virt' def getcompiled(self, func, view=False): t = Translator(func, simplifying=True) @@ -44,8 +41,8 @@ return x + y - 42 f = self.getcompiled(testfn)#, view=True) - assert f(2, 3) == testfn(2, 3) assert f(-2, 3) == testfn(-2, 3) + assert f(2, 5) == testfn(2, 5) def test_loop(self): def testfn(lim=int): @@ -61,4 +58,80 @@ assert f(10) == testfn(10) assert f(100) == testfn(100) assert f(1000) == testfn(1000) - + + def test_factor(self): + def factor(n=int): + i = 2 + while i < n: + if n % i == 0: + return i + i += 1 + return i + f = self.getcompiled(factor) + + assert f(25) == 5 + assert f(27) == 3 + assert f(17*13) == 13 + assert f(29) == 29 + + def test_from_psyco(self): + def f1(n=int): + "Arbitrary test function." + i = 0 + x = 1 + while i 10: + return 10 + elif x >= 5: + return 5 + elif x < -10: + return -10 + elif x <= -5: + return -5 + elif x != 1: + return 1 + else: + return x + g = self.getcompiled(f) + for i in range(-20, 20): + assert g(i) == f(i) + + def dont_test_overflow(self): + def f(x=int, y=int): + try: + return ovfcheck(x*y) + except OverflowError: + return 0 + g = self.getcompiled(f, view=True) + assert f(3, 4) == g(3, 4) + big = 1000000000 + assert f(big, big) == g(big, big) + +class TestAsmAfterAllocation(TestAsm): + + processor = 'virtfinite' + + +class TestAsmPPC(TestAsm): + + processor = 'ppc' + + def setup_class(cls): + if not hasattr(os, "uname") or os.uname()[-1] != 'Power Macintosh': + py.test.skip('asm generation only on PPC') + + Modified: pypy/branch/hl-backend/pypy/translator/c/extfunc.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/extfunc.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/extfunc.py Fri Oct 14 17:44:56 2005 @@ -4,7 +4,8 @@ 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, ll_strtod, ll_stackless +from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod +from pypy.rpython.module import ll_stackless, ll_stack from pypy.module.thread.rpython import ll_thread @@ -50,6 +51,8 @@ ll_thread.ll_thread_start: 'LL_thread_start', ll_thread.ll_thread_get_ident: 'LL_thread_get_ident', ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', + ll_stack.ll_stack_unwind: 'LL_stack_unwind', + ll_stack.ll_stack_too_big: 'LL_stack_too_big', } #______________________________________________________ Modified: pypy/branch/hl-backend/pypy/translator/c/funcgen.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/funcgen.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/funcgen.py Fri Oct 14 17:44:56 2005 @@ -234,7 +234,11 @@ lst.append(self.expr(op.result)) lst.append(err) line = '%s(%s);' % (macro, ', '.join(lst)) - yield line + if '\n' in line: + for subline in line.split('\n'): + yield subline + else: + yield line if line.find(err) >= 0: reachable_err = len(to_release) to_release.append(op.result) @@ -404,11 +408,11 @@ # skip assignment of 'void' return value r = self.expr(op.result) line = '%s = %s' % (r, line) - line = '%s %s' % (line, self.check_directcall_result(op, err)) + line = '%s\n%s' % (line, self.check_directcall_result(op, err)) return line def check_directcall_result(self, op, err): - return 'if (RPyExceptionOccurred()) FAIL(%s);' % err + return 'if (RPyExceptionOccurred())\n\tFAIL(%s);' % err # low-level operations def generic_get(self, op, sourceexpr): @@ -418,7 +422,7 @@ # need to adjust the refcount of the result only for PyObjects if T == PyObjPtr: result.append(self.pyobj_incref_expr(newvalue, T)) - result = '\t'.join(result) + result = '\n'.join(result) if T is Void: result = '/* %s */' % result return result @@ -429,7 +433,7 @@ # insert write barrier T = self.lltypemap(op.args[2]) self.gcpolicy.write_barrier(result, newvalue, T, targetexpr) - result = '\t'.join(result) + result = '\n'.join(result) if T is Void: result = '/* %s */' % result return result @@ -513,12 +517,20 @@ eresult = self.expr(op.result) if VARPART.OF is Void: # strange esize = 'sizeof(%s)' % (cdecl(typename, ''),) + result = '' else: - esize = 'sizeof(%s)+((%s-1)*sizeof(%s))' % (cdecl(typename, ''), - elength, - cdecl(itemtypename, '')) - result = self.gcpolicy.zero_malloc(TYPE, esize, eresult, err) - result += '\t%s->%s = %s;' % (eresult, lenfld, elength) + itemtype = cdecl(itemtypename, '') + result = 'OP_MAX_VARSIZE(%s, %s, %s);\n' % ( + elength, + itemtype, + err) + esize = 'sizeof(%s)-sizeof(%s)+%s*sizeof(%s)' % ( + cdecl(typename, ''), + itemtype, + elength, + itemtype) + result += self.gcpolicy.zero_malloc(TYPE, esize, eresult, err) + result += '\n%s->%s = %s;' % (eresult, lenfld, elength) return result def OP_CAST_POINTER(self, op, err): Modified: pypy/branch/hl-backend/pypy/translator/c/gc.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/gc.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/gc.py Fri Oct 14 17:44:56 2005 @@ -107,10 +107,12 @@ if increfstmt: result.append(increfstmt) if decrefstmt: - result.insert(0, '{ %s = %s;' % ( + result.insert(0, '%s = %s;' % ( cdecl(self.db.gettype(T), 'prev'), targetexpr)) result.append(decrefstmt) + result[:] = ['\t%s' % line for line in result] + result[0] = '{' + result[0] result.append('}') def generic_dealloc(self, expr, T): @@ -348,7 +350,7 @@ is_varsize, err) if gcinfo and gcinfo.finalizer: - result += ('\tGC_REGISTER_FINALIZER(%s, %s, NULL, NULL, NULL);' + result += ('\nGC_REGISTER_FINALIZER(%s, %s, NULL, NULL, NULL);' % (eresult, gcinfo.finalizer)) return result Modified: pypy/branch/hl-backend/pypy/translator/c/genc.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/genc.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/genc.py Fri Oct 14 17:44:56 2005 @@ -11,7 +11,7 @@ from pypy.rpython import lltype from pypy.tool.udir import udir -class CBuilder: +class CBuilder(object): c_source_filename = None _compiled = False symboltable = None @@ -23,7 +23,7 @@ if libraries is None: libraries = [] - self.libraries = libraries + self.libraries = libraries def generate_source(self): assert self.c_source_filename is None @@ -132,7 +132,8 @@ # ____________________________________________________________ -SPLIT_CRITERIA = 170 +#SPLIT_CRITERIA = 32767 # enable to support VC++ 6.0 +SPLIT_CRITERIA = 65535 # support VC++ 7.2 MARKER = '/*/*/' # provide an easy way to split after generating @@ -148,9 +149,7 @@ def set_strategy(self, path): all_nodes = list(self.database.globalcontainers()) - # split off non-function nodes - # win32 has a problem: compiles but infinite recursion etc. - # trytocicumvent this by placing all non-func nodes into one file. + # split off non-function nodes. We don't try to optimize these, yet. funcnodes = [] othernodes = [] for node in all_nodes: @@ -158,7 +157,8 @@ funcnodes.append(node) else: othernodes.append(node) - if 1 or len(funcnodes) >= SPLIT_CRITERIA:##!! + # for now, only split for stand-alone programs. + if self.database.standalone: self.one_source_file = False self.funcnodes = funcnodes self.othernodes = othernodes @@ -180,15 +180,26 @@ def getothernodes(self): return self.othernodes[:] - def splitfuncnodes(self): - # silly first split, just by node count - # XXX filter constant stuff off and put it elsewhere - nodes = self.funcnodes[:] - nchunks = len(nodes) // SPLIT_CRITERIA or 1 - chunksize = (len(nodes) + nchunks - 1) // nchunks - while nodes: - yield self.uniquecname('implement.c'), nodes[:chunksize] - del nodes[:chunksize] + def splitnodesimpl(self, basecname, nodes, nextra, nbetween): + # produce a sequence of nodes, grouped into files + # which have no more than SPLIT_CRITERIA lines + used = nextra + part = [] + for node in nodes: + impl = list(node.implementation()) + if not impl: + continue + cost = len(impl) + nbetween + if used + cost > SPLIT_CRITERIA and part: + # split if criteria met, unless we would produce nothing. + yield self.uniquecname(basecname), part + part = [] + used = nextra + part.append( (node, impl) ) + used += cost + # generate left pieces + if part: + yield self.uniquecname(basecname), part def gen_readable_parts_of_source(self, f): if self.one_source_file: @@ -266,26 +277,33 @@ print >> fc, '/***********************************************************/' fc.close() - name = self.uniquecname('nonfuncnodes.c') - print >> f, '/* %s */' % name - fc = self.makefile(name) - print >> fc, '/***********************************************************/' - print >> fc, '/*** Non-function Implementations ***/' - print >> fc - print >> fc, '#define PYPY_NOT_MAIN_FILE' - print >> fc, '#include "common_header.h"' - print >> fc, '#include "structdef.h"' - print >> fc, '#include "forwarddecl.h"' - print >> fc - print >> fc, '#include "src/g_include.h"' - print >> fc - print >> fc, MARKER - for node in self.getothernodes(): - render_nonempty(node.implementation()) - print >> fc, '/***********************************************************/' - fc.close() + nextralines = 11 + 1 + for name, nodesimpl in self.splitnodesimpl('nonfuncnodes.c', + self.othernodes, + nextralines, 1): + print >> f, '/* %s */' % name + fc = self.makefile(name) + print >> fc, '/***********************************************************/' + print >> fc, '/*** Non-function Implementations ***/' + print >> fc + print >> fc, '#define PYPY_NOT_MAIN_FILE' + print >> fc, '#include "common_header.h"' + print >> fc, '#include "structdef.h"' + print >> fc, '#include "forwarddecl.h"' + print >> fc + print >> fc, '#include "src/g_include.h"' + print >> fc + print >> fc, MARKER + for node, impl in nodesimpl: + print >> fc, '\n'.join(impl) + print >> fc, MARKER + print >> fc, '/***********************************************************/' + fc.close() - for name, nodes in self.splitfuncnodes(): + nextralines = 8 + len(self.preimpl) + 4 + 1 + for name, nodesimpl in self.splitnodesimpl('implement.c', + self.funcnodes, + nextralines, 1): print >> f, '/* %s */' % name fc = self.makefile(name) print >> fc, '/***********************************************************/' @@ -302,9 +320,9 @@ print >> fc, '#include "src/g_include.h"' print >> fc print >> fc, MARKER - linecount = 12 + len(self.preimpl) - for node in nodes: - linecount += render_nonempty(node.implementation()) + for node, impl in nodesimpl: + print >> fc, '\n'.join(impl) + print >> fc, MARKER print >> fc, '/***********************************************************/' fc.close() print >> f Modified: pypy/branch/hl-backend/pypy/translator/c/src/address.h ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/src/address.h (original) +++ pypy/branch/hl-backend/pypy/translator/c/src/address.h Fri Oct 14 17:44:56 2005 @@ -5,9 +5,9 @@ /*** binary operations ***/ -#define OP_ADR_DELTA(x,y,r,err) r = ((x) - (y)) -#define OP_ADR_SUB(x,y,r,err) r = ((x) - (y)) -#define OP_ADR_ADD(x,y,r,err) r = ((x) + (y)) +#define OP_ADR_DELTA(x,y,r,err) r = ((char *)(x) - (char *)(y)) +#define OP_ADR_SUB(x,y,r,err) r = ((char *)(x) - (y)) +#define OP_ADR_ADD(x,y,r,err) r = ((char *)(x) + (y)) #define OP_ADR_EQ(x,y,r,err) r = ((x) == (y)) #define OP_ADR_NE(x,y,r,err) r = ((x) != (y)) Modified: pypy/branch/hl-backend/pypy/translator/c/src/g_include.h ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/src/g_include.h (original) +++ pypy/branch/hl-backend/pypy/translator/c/src/g_include.h Fri Oct 14 17:44:56 2005 @@ -41,6 +41,8 @@ # include "src/ll_stackless.h" #endif +#include "src/stack.h" + #ifdef PYPY_STANDALONE # include "src/main.h" #endif Modified: pypy/branch/hl-backend/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/branch/hl-backend/pypy/translator/c/src/ll_stackless.h Fri Oct 14 17:44:56 2005 @@ -32,6 +32,7 @@ slp_frame_t* slp_new_frame(int size, int state); long LL_stackless_stack_frames_depth(void); void slp_main_loop(void); +char LL_stackless_stack_too_big(void); #ifndef PYPY_NOT_MAIN_FILE @@ -53,6 +54,19 @@ return f; } +void LL_stackless_stack_unwind(void) +{ + if (slp_frame_stack_top) + goto resume; + + slp_frame_stack_top = slp_frame_stack_bottom = + slp_new_frame(sizeof(slp_frame_t), 0); + return ; + + resume: + slp_frame_stack_top = NULL; +} + /* example function for testing */ @@ -62,7 +76,7 @@ goto resume; slp_frame_stack_top = slp_frame_stack_bottom = - slp_new_frame(sizeof(slp_frame_t), 0); + slp_new_frame(sizeof(slp_frame_t), 1); return -1; resume: @@ -82,7 +96,6 @@ #include "slp_state_decoding.h" - void slp_main_loop(void) { int state, signature; @@ -132,7 +145,8 @@ int slp_standalone_entry_point(RPyListOfString *argv) { - int result = PYPY_STANDALONE(argv); + int result; + result = PYPY_STANDALONE(argv); if (slp_frame_stack_bottom) { slp_main_loop(); result = (int) slp_retval_long; @@ -142,4 +156,5 @@ #endif /* PYPY_NOT_MAIN_FILE */ -#endif USE_STACKLESS +#endif /* USE_STACKLESS */ + Modified: pypy/branch/hl-backend/pypy/translator/c/src/mem.h ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/src/mem.h (original) +++ pypy/branch/hl-backend/pypy/translator/c/src/mem.h Fri Oct 14 17:44:56 2005 @@ -3,6 +3,17 @@ /*** C header subsection: operations on LowLevelTypes ***/ +/* a reasonably safe bound on the largest allowed argument value + that we can pass to malloc. This is used for var-sized mallocs + to compute the largest allowed number of items in the array. */ +#define MAXIMUM_MALLOCABLE_SIZE (LONG_MAX-4096) + +#define OP_MAX_VARSIZE(numitems, itemtype, err) { \ + if ((numitems) > (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype))) \ + FAIL_EXCEPTION(err, PyExc_MemoryError, "addr space overflow"); \ + } + + /* XXX hack to initialize the refcount of global structures: officially, we need a value equal to the number of references to this global from other globals, plus one. This upper bound "approximation" will do... */ Modified: pypy/branch/hl-backend/pypy/translator/c/src/support.h ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/src/support.h (original) +++ pypy/branch/hl-backend/pypy/translator/c/src/support.h Fri Oct 14 17:44:56 2005 @@ -34,8 +34,13 @@ PyObject* PyList_Pack(int n, ...); PyObject* PyDict_Pack(int n, ...); PyObject* PyTuple_Pack(int n, ...); +#if PY_VERSION_HEX >= 0x02030000 /* 2.3 */ +# define PyObject_GetItem1 PyObject_GetItem +# define PyObject_SetItem1 PyObject_SetItem +#else PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index); PyObject* PyObject_SetItem1(PyObject* obj, PyObject* index, PyObject* v); +#endif PyObject* CallWithShape(PyObject* callable, PyObject* shape, ...); PyObject* decode_arg(PyObject* fname, int position, PyObject* name, PyObject* vargs, PyObject* vkwds, PyObject* def); @@ -168,10 +173,7 @@ } #endif -#if PY_VERSION_HEX >= 0x02030000 /* 2.3 */ -# define PyObject_GetItem1 PyObject_GetItem -# define PyObject_SetItem1 PyObject_SetItem -#else +#if PY_VERSION_HEX < 0x02030000 /* 2.3 */ /* for Python 2.2 only */ PyObject* PyObject_GetItem1(PyObject* obj, PyObject* index) { Modified: pypy/branch/hl-backend/pypy/translator/c/stackless.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/stackless.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/stackless.py Fri Oct 14 17:44:56 2005 @@ -11,16 +11,18 @@ from pypy.translator.c.support import cdecl from pypy.translator.c.funcgen import FunctionCodeGenerator - class StacklessData: def __init__(self): self.frame_types = {} - self.globalstatecounter = 1 self.allsignatures = {} self.decode_table = [] + # start the decoding table with entries for the functions that # are written manually in ll_stackless.h + self.registerunwindable('LL_stackless_stack_unwind', + lltype.FuncType([], lltype.Void), + resume_points=1) self.registerunwindable('LL_stackless_stack_frames_depth', lltype.FuncType([], lltype.Signed), resume_points=1) @@ -36,12 +38,17 @@ for n in range(1, resume_points): self.decode_table.append(('NULL', n)) - def get_frame_type(self, n_integers, n_floats, n_pointers): - key = n_integers, n_floats, n_pointers + def get_frame_type(self, counts): + """Return the frame struct name, + named after the number of saved variables of each kind. + counts is a sequence of numbers, ordered like STATE_TYPES + """ + key = tuple(counts) try: return self.frame_types[key] except KeyError: - name = 'slp_frame_%d_%d_%d_s' % key + nums = "_".join([str(c) for c in key]) + name = 'slp_frame_%s_s' % nums self.frame_types[key] = name return name @@ -56,37 +63,38 @@ for line in sg.preimpl: print >> fc, line print >> fc, '#include "src/g_include.h"' + items = self.frame_types.items() items.sort() - for (n_integers, n_floats, n_pointers), structname in items: - types = (['long']*n_integers + - ['double']*n_floats + - ['void *']*n_pointers) - varnames = (['l%d' % i for i in range(n_integers)] + - ['d%d' % i for i in range(n_floats)] + - ['v%d' % i for i in range(n_pointers)]) + for counts, structname in items: + varnames = [] + for count, vartype in zip(counts, STATE_TYPES): + varnames.extend([(vartype.ctype, '%s%d' % (vartype.prefix, i)) + for i in range(count)]) + + # generate the struct definition fields = [] - for type, varname in zip(types, varnames): + for type, varname in varnames: fields.append('%s %s;' % (type, varname)) print >> fi, 'struct %s { slp_frame_t header; %s };' % ( structname, ' '.join(fields)) + # generate the 'save_' function arguments = ['int state'] saving_lines = [] - for type, varname in zip(types, varnames): + for type, varname in varnames: arguments.append('%s %s' % (type, varname)) saving_lines.append('((struct %s*) f)->%s = %s;' % ( structname, varname, varname)) - head = 'void *save_%(name)s(%(arguments)s);' + head = 'void save_%(name)s(%(arguments)s);' code = str(py.code.Source(''' - void *save_%(name)s(%(arguments)s) + void save_%(name)s(%(arguments)s) { slp_frame_t* f = slp_new_frame(sizeof(struct %(name)s), state); slp_frame_stack_bottom->f_back = f; slp_frame_stack_bottom = f; %(saving_lines)s - return NULL; } ''')) argdict = {'name': structname, @@ -110,11 +118,10 @@ functiontype = sg.database.gettype(lltype.Ptr(FUNC)) callexpr = '((%s) fn) (%s);' % (cdecl(functiontype, ''), ', '.join(dummyargs)) - globalretvalvartype = simplified_type(FUNC.RESULT) + globalretvalvartype = storage_type(FUNC.RESULT) if globalretvalvartype is not None: - globalretvalvarname = RETVALVARS[globalretvalvartype] - callexpr = '%s = (%s) %s' % (globalretvalvarname, - globalretvalvartype, + callexpr = '%s = (%s) %s' % (globalretvalvartype.global_name, + globalretvalvartype.ctype, callexpr) print >> fi, '\t' + callexpr print >> fi, '\tbreak;' @@ -163,11 +170,10 @@ # record extra data needed to generate the slp_*.h tables: # find the signatures of all functions slpdata = self.db.stacklessdata - argtypes = [erase_ptr_type(v.concretetype) + argtypes = [signature_type(self.lltypemap(v)) for v in self.graph.getargs()] argtypes = [T for T in argtypes if T is not lltype.Void] - import sys - rettype = erase_ptr_type(self.graph.getreturnvar().concretetype) + rettype = signature_type(self.lltypemap(self.graph.getreturnvar())) FUNC = lltype.FuncType(argtypes, rettype) slpdata.registerunwindable(self.functionname, FUNC, resume_points = len(self.resumeblocks)) @@ -179,49 +185,38 @@ stacklessdata = self.db.stacklessdata block = self.currentblock curpos = block.operations.index(op) - - # XXX obscure: find all variables that are produced before 'op' - vars = [] - for v in block.inputargs: - vars.append(v) - for op1 in block.operations[:curpos]: - vars.append(op1.result) + vars = list(variables_to_save_across_op(block, curpos)) # get the simplified frame struct that can store these vars - counts = {"long": [], - "double": [], - "void*": []} + counts = dict([(type, []) for type in STATE_TYPES]) variables_to_restore = [] for v in vars: - st = simplified_type(erase_ptr_type(v.concretetype)) + st = storage_type(self.lltypemap(v)) if st is not None: # ignore the Voids varname = self.expr(v) - # XXX hackish: the name of the field in the structure is - # computed from the 1st letter of the 'st' type, counting - # from 0 for each of the 'st' types independently + # The name of the field in the structure is computed from + # the prefix of the 'st' type, counting from 0 for each + # of the 'st' types independently variables_to_restore.append((v, '%s%d' % ( - st[0], len(counts[st])))) - counts[st].append('(%s)%s' % (st, varname)) - structname = stacklessdata.get_frame_type(len(counts["long"]), - len(counts["double"]), - len(counts["void*"])) + st.prefix, len(counts[st])))) + counts[st].append('(%s)%s' % (st.ctype, varname)) + structname = stacklessdata.get_frame_type([len(counts[st]) for st in STATE_TYPES]) # reorder the vars according to their type - vars = counts["long"] + counts["double"] + counts["void*"] + vars = sum([counts[st] for st in STATE_TYPES],[]) # generate the 'save:' line, e.g. # save_0: return (int) save_frame_1(0, (long) n); savelabel = 'save_%d' % len(self.savelines) - arguments = ['%d' % stacklessdata.globalstatecounter] + vars - stacklessdata.globalstatecounter += 1 + + # The globally unique number for our state + # is the total number of saved states so far + globalstatecounter = len(stacklessdata.decode_table) + len(self.savelines) + + arguments = ['%d' % globalstatecounter] + vars + savecall = 'save_%s(%s);' % (structname, ', '.join(arguments)) - retvar = self.graph.getreturnvar() - if retvar.concretetype is lltype.Void: - savecall += ' return;' - else: - retvartype = self.lltypename(retvar) - savecall = 'return (%s) %s' % (cdecl(retvartype, ''), - savecall) + savecall += ' return %s;' % self.error_return_value() self.savelines.append('%s: %s' % (savelabel, savecall)) # generate the resume block, e.g. @@ -238,9 +233,9 @@ varname, cdecl(vartype, ''), structname, fieldname)) retvarname = self.expr(op.result) retvartype = self.lltypename(op.result) - retvarst = simplified_type(erase_ptr_type(op.result.concretetype)) + retvarst = storage_type(self.lltypemap(op.result)) if retvarst is not None: - globalretvalvarname = RETVALVARS[retvarst] + globalretvalvarname = retvarst.global_name lines.append('%s = (%s) %s;' % ( retvarname, cdecl(retvartype, ''), globalretvalvarname)) lines.append('goto %s;' % (resumelabel,)) @@ -248,17 +243,18 @@ # add the checks for the unwinding case just after the directcall # in the source - unwind_check = "if (slp_frame_stack_bottom) goto %s;" % (savelabel,) + unwind_check = "if (slp_frame_stack_bottom)\n\tgoto %s;" % (savelabel,) exception_check = (super(SlpFunctionCodeGenerator, self) .check_directcall_result(op, err)) - return '%s\n %s:\n\t%s' % (unwind_check, - resumelabel, - exception_check) + return '%s\n %s:\n%s' % (unwind_check, + resumelabel, + exception_check) -def erase_ptr_type(T): +def signature_type(T): """Return T unless it's a pointer type, in which case we return a general basic pointer type. + The returned type must have the same behaviour when put on the C stack. """ if isinstance(T, lltype.Ptr): return Address @@ -266,20 +262,55 @@ return T -def simplified_type(T): +class StateVariableType: + def __init__(self, ctype, prefix, global_name): + self.ctype = ctype + self.prefix = prefix + self.global_name = global_name + +STATE_TYPES = [ + StateVariableType('long', 'l', 'slp_retval_long'), + StateVariableType('void*', 'p', 'slp_retval_voidptr'), + StateVariableType('double', 'd', 'slp_retval_double'), + ] + +def storage_type(T): + """Return the type used to save values of this type + """ if T is lltype.Void: return None elif T is lltype.Float: - return "double" - elif T is Address: - return "void*" + return STATE_TYPES[ 2 ] + elif T is Address or isinstance(T, lltype.Ptr): + return STATE_TYPES[ 1 ] elif isinstance(T, lltype.Primitive): - return "long" # large enough for all other primitives + return STATE_TYPES[ 0 ] # long is large enough for all other primitives else: raise Exception("don't know about %r" % (T,)) -RETVALVARS = { - "double": "slp_retval_double", - "long" : "slp_retval_long", - "void*" : "slp_retval_voidptr", - } +def variables_to_save_across_op(block, opindex): + # variable lifetime detection: + # 1) find all variables that are produced before the operation + produced = {} + for v in block.inputargs: + produced[v] = True + for op1 in block.operations[:opindex]: + produced[op1.result] = True + # 2) find all variables that are used by or after the operation + consumed = {} + for op1 in block.operations[opindex:]: + for v in op1.args: + if isinstance(v, Variable): + consumed[v] = True + if isinstance(block.exitswitch, Variable): + consumed[block.exitswitch] = True + for link in block.exits: + for v in link.args: + if isinstance(v, Variable): + consumed[v] = True + # 3) variables that are atomic and not consumed after the operation + # don't have to have their lifetime extended; that leaves only + # the ones that are not atomic or consumed. + for v in produced: + if v in consumed or not v.concretetype._is_atomic(): + yield v Modified: pypy/branch/hl-backend/pypy/translator/c/test/test_annotated.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/test/test_annotated.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/test/test_annotated.py Fri Oct 14 17:44:56 2005 @@ -1,5 +1,5 @@ import autopath -import py +import py, sys from pypy.translator.tool.cbuild import skip_missing_compiler from pypy.translator.translator import Translator @@ -167,13 +167,13 @@ assert fn(-4.5) == 92.125 assert fn(4.5) == 90.125 - def test_recursion_detection(self): - def f(n=int, accum=int): - if n == 0: - return accum - else: - return f(n-1, accum*n) + def test_memoryerror(self): + def f(i=int): + lst = [0]*i + lst[-1] = 5 + return lst[0] fn = self.getcompiled(f) - assert fn(7, 1) == 5040 - py.test.skip("recursion detection: in-progress") - py.test.raises(RuntimeError, fn, -1, 0) + assert fn(1) == 5 + assert fn(2) == 0 + py.test.raises(MemoryError, fn, sys.maxint//2+1) + py.test.raises(MemoryError, fn, sys.maxint) Modified: pypy/branch/hl-backend/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/test/test_extfunc.py Fri Oct 14 17:44:56 2005 @@ -23,14 +23,18 @@ 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 + t3 = f1() + t4 = time.clock() + t5 = f1() + t6 = time.clock() + # time.clock() and t1() might have a different notion of zero, so + # we can only subtract two numbers returned by the same function. + assert 0 <= t2-t0 + assert 0 <= t3-t1 <= t4-t0 + assert 0 <= t4-t2 <= t5-t1 <= t6-t0 + assert 0 <= t5-t3 <= t6-t2 + assert 0 <= t6-t4 def test_time_sleep(): def does_nothing(): Modified: pypy/branch/hl-backend/pypy/translator/c/test/test_lladdresses.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/test/test_lladdresses.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/test/test_lladdresses.py Fri Oct 14 17:44:56 2005 @@ -71,4 +71,18 @@ res = fc() assert res - +def test_pointer_comparison(): + def f(): + result = 0 + for addr1 in [raw_malloc(1), NULL]: + addr2 = addr1 + 1 + result = result * 2 + int(addr1 == addr2) + result = result * 2 + int(addr1 != addr2) + result = result * 2 + int(addr1 < addr2) + result = result * 2 + int(addr1 <= addr2) + result = result * 2 + int(addr1 > addr2) + result = result * 2 + int(addr1 >= addr2) + return result + fc = compile(f, []) + res = fc() + assert res == int('011100' * 2, 2) Modified: pypy/branch/hl-backend/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/test/test_standalone.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/test/test_standalone.py Fri Oct 14 17:44:56 2005 @@ -1,8 +1,8 @@ from pypy.translator.translator import Translator -from pypy.translator.tool.cbuild import build_executable +from pypy.translator.tool.cbuild import build_executable from pypy.annotation.model import SomeList, SomeString from pypy.annotation.listdef import ListDef -from pypy.rpython.objectmodel import stack_frames_depth +from pypy.rpython.objectmodel import stack_unwind, stack_frames_depth, stack_too_big import os @@ -14,19 +14,19 @@ 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() + cbuilder.compile() data = cbuilder.cmdexec('hi there') assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') -def test_stack_unwind(): +def test_stack_depth(): def g1(): "just to check Void special cases around the code" def g2(ignored): @@ -64,6 +64,64 @@ data = wrap_stackless_function(fn) assert data.strip() == '10' +def test_stackless_manytimes(): + def f(n): + if n > 0: + stack_frames_depth() + res = f(n-1) + else: + res = stack_frames_depth(), 1 + return res + + def fn(): + count0, _ = f(0) + count10, _ = f(100) + return count10 - count0 + + data = wrap_stackless_function(fn) + assert data.strip() == '100' + +def test_stackless_arguments(): + def f(n, d, t): + if n > 0: + res = f(n-1, d, t) + else: + res = stack_frames_depth(), d, t + return res + + def fn(): + count0, d, t = f(0, 5.5, (1, 2)) + count10, d, t = f(10, 5.5, (1, 2)) + return "[" + str(count10 - count0) + ", " + str(d) + ", " + str(t[0]) + ", " + str(t[1]) + "]" + + data = wrap_stackless_function(fn) + assert eval(data) == [10, 5.5, 1, 2] + + +def test_stack_too_big(): + def f1(): + return stack_too_big() + def f2(): + return lst[1]() + def f3(): + return lst[2]() + def f4(): + return lst[3]() + def f5(): + return lst[4]() + lst = [None,f1,f2,f3,f4,f5] + + def f(n): + if lst[5](): + return n + return f(n)+1 + + def fn(): + return f(0) + data = wrap_stackless_function(fn) + assert int(data.strip()) > 500 + + def wrap_stackless_function(fn): def entry_point(argv): @@ -72,10 +130,29 @@ t = Translator(entry_point) s_list_of_strings = SomeList(ListDef(None, SomeString())) - t.annotate([s_list_of_strings]) + ann = t.annotate([s_list_of_strings]) t.specialize() cbuilder = t.cbuilder(standalone=True) cbuilder.stackless = True cbuilder.generate_source() - cbuilder.compile() + cbuilder.compile() return cbuilder.cmdexec('') + +def test_stack_unwind(): + def f(): + stack_unwind() + return 42 + + data = wrap_stackless_function(f) + assert int(data.strip()) == 42 + +def test_auto_stack_unwind(): + def f(n): + if n == 1: + return 1 + return (n+f(n-1)) % 1291 + + def fn(): + return f(10**6) + data = wrap_stackless_function(fn) + assert int(data.strip()) == 704 Modified: pypy/branch/hl-backend/pypy/translator/c/test/test_typed.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/c/test/test_typed.py (original) +++ pypy/branch/hl-backend/pypy/translator/c/test/test_typed.py Fri Oct 14 17:44:56 2005 @@ -1,5 +1,6 @@ import autopath import sys +import py from py.test import raises from pypy.translator.translator import Translator from pypy.translator.test import snippet @@ -398,3 +399,13 @@ f = self.getcompiled(fn) for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]: assert f(*args) == intmask(fn(*args)) + + def test_recursion_detection(self): + def f(n=int, accum=int): + if n == 0: + return accum + else: + return f(n-1, accum*n) + fn = self.getcompiled(f) + assert fn(7, 1) == 5040 + py.test.raises(RuntimeError, fn, -1, 0) Modified: pypy/branch/hl-backend/pypy/translator/goal/bench-windows.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/goal/bench-windows.py (original) +++ pypy/branch/hl-backend/pypy/translator/goal/bench-windows.py Fri Oct 14 17:44:56 2005 @@ -78,7 +78,7 @@ CREATIONFLAGS = win32con.HIGH_PRIORITY_CLASS print "configured to run under high priority" -BENCH_EXECONFIG = 'bench_windows_exe.txt' +BENCH_EXECONFIG = '_bench_windows_exe.txt' bench_exe = None def reference(progname): @@ -103,16 +103,22 @@ size += os.path.getsize(win32api.GetModuleFileName(int(dll))) return ver, size -def run_pystone(executable=reference('python'), n=0): - argstr = PYSTONE_CMD % (str(n) and n or '') - txt = run_cmd('%s -c "%s"' % (executable, argstr)) +def run_pystone(executable=reference('python'), n=0, rpy=False): + if rpy: + txt = run_cmd('%s pystone' % executable) + else: + argstr = PYSTONE_CMD % (str(n) and n or '') + txt = run_cmd('%s -c "%s"' % (executable, argstr)) res = get_result(txt, PYSTONE_PATTERN) print res return res -def run_richards(executable=reference('python'), n=20): - argstr = RICHARDS_CMD % n - txt = run_cmd('%s -c "%s"' % (executable, argstr)) +def run_richards(executable=reference('python'), n=20, rpy=False): + if rpy: + txt = run_cmd('%s richards' % executable) + else: + argstr = RICHARDS_CMD % n + txt = run_cmd('%s -c "%s"' % (executable, argstr)) res = get_result(txt, RICHARDS_PATTERN) print res return res @@ -122,7 +128,7 @@ exes.sort() return exes -STAT_FILE = 'bench_windows.dump' +STAT_FILE = '_bench_windows.dump' def load_stats(statfile=STAT_FILE): try: dic = pickle.load(file(statfile, 'rb')) @@ -134,9 +140,11 @@ pickle.dump(dic, file(statfile, 'wb')) HEADLINE = '''\ -executable richards pystone size (MB)''' +executable richards pystone size (MB)''' FMT = '''\ -%-27s''' + '%5d %5.1fx %7.1f %5.1fx %5.2f' +%-27s''' + '%5d %5.1fx' + ' %9.1f %5.1fx %5.3f' +FMT2 = '''\ +%-27s''' + '%5.3f %5.1f/' + ' %9.1f %5.1f/ %5.3f' def main(): print 'getting the richards reference' @@ -149,25 +157,30 @@ exename = os.path.splitext(exe)[0] mtime = os.path.getmtime(exe) size = os.path.getsize(exe) + rpy = size < 500000 key = md5.new(file(exe,'rb').read()).digest() if key in prior: print 'skipped', exename resdic[key] = prior[key][:2] + (exename, mtime, size) else: - resdic[key] = (run_richards(exe, 2), run_pystone(exe, 20000), + resdic[key] = (run_richards(exe, 2,rpy), run_pystone(exe, 20000, rpy), exename, mtime, size) prior[key] = resdic[key] # save result, temporarily save_stats(prior) save_stats(resdic) # save cleaned result - res = [ (mtime, exe, size, rich, stone) + res = [ (stone / rich, exe, size, rich, stone) for rich, stone, exe, mtime, size in resdic.values()] version, size = run_version_size() - res.append( (9e9, 'python %s' % version, size, ref_rich, ref_stone) ) + res.append( (1.0, 'python %s' % version, size, ref_rich, ref_stone) ) res.sort() print HEADLINE - for mtime, exe, size, rich, stone in res: - print FMT % (exe, rich, rich / ref_rich, stone, ref_stone / stone, - size / float(1024 * 1024)) + for speed2, exe, size, rich, stone in res: + if speed2 <= 1.0: + print FMT % (exe, rich, rich / ref_rich, stone, ref_stone / stone, + size / float(1024 * 1024)) + else: + print FMT2 % (exe, rich, ref_rich / rich, stone, stone / ref_stone, + size / float(1024 * 1024)) if __name__ == '__main__': main() Modified: pypy/branch/hl-backend/pypy/translator/goal/driver.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/goal/driver.py (original) +++ pypy/branch/hl-backend/pypy/translator/goal/driver.py Fri Oct 14 17:44:56 2005 @@ -16,6 +16,7 @@ DEFAULT_OPTIONS = optparse.Values(defaults={ 'gc': 'ref', + 'stackless': False, 'debug': True, 'insist': False, 'backend': 'c', @@ -189,6 +190,7 @@ gcpolicy = gc.NoneGcPolicy cbuilder = translator.cbuilder(standalone=standalone, gcpolicy=gcpolicy) + cbuilder.stackless = opt.stackless c_source_filename = cbuilder.generate_source() self.log.info("written: %s" % (c_source_filename,)) self.cbuilder = cbuilder Modified: pypy/branch/hl-backend/pypy/translator/goal/targetnopstandalone.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/goal/targetnopstandalone.py (original) +++ pypy/branch/hl-backend/pypy/translator/goal/targetnopstandalone.py Fri Oct 14 17:44:56 2005 @@ -1,3 +1,12 @@ +""" +A simple standalone target. + +The target below specifies None as the argument types list. +This is a case treated specially in driver.py . If the list +of input types is empty, it is meant to be a list of strings, +actually implementing argv of the executable. +""" + import os, sys def debug(msg): @@ -6,11 +15,10 @@ # __________ Entry point __________ def entry_point(argv): - debug("done!") + debug("hello world") return 0 # _____ Define and setup target ___ def target(*args): return entry_point, None - Modified: pypy/branch/hl-backend/pypy/translator/goal/targetrichards.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/goal/targetrichards.py (original) +++ pypy/branch/hl-backend/pypy/translator/goal/targetrichards.py Fri Oct 14 17:44:56 2005 @@ -1,7 +1,9 @@ from pypy.translator.goal import richards +from pypy.translator.tool.taskengine import SimpleTaskEngine entry_point = richards.entry_point + # _____ Define and setup target ___ def target(*args): @@ -18,3 +20,34 @@ richards.main(iterations=5) +class Tasks(SimpleTaskEngine): + + def task_annotate(self): + pass + task_annotate.task_deps = [] + + def task + + +""" sketch of tasks for translation: + +annotate: # includes annotation and annotatation simplifications + +rtype: annotate + +backendoptimisations: rtype # make little sense otherwise + +source_llvm: backendoptimisations, rtype, annotate + +source_c: ?backendoptimisations, ?rtype, ?annotate + +compile_c : source_c + +compile_llvm: source_llvm + +run_c: compile_c + +run_llvm: compile_llvm + +""" + Modified: pypy/branch/hl-backend/pypy/translator/goal/translate_pypy.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/goal/translate_pypy.py (original) +++ pypy/branch/hl-backend/pypy/translator/goal/translate_pypy.py Fri Oct 14 17:44:56 2005 @@ -49,6 +49,7 @@ '1_backend': [OPT(('-b', '--backend'), "Backend", ['c', 'llvm'])], '2_gc': [OPT(('--gc',), "Garbage collector", ['boehm', 'ref', 'none'])], + '3_stackless': [OPT(('--stackless',), "Stackless code generation", True)], }, @@ -97,6 +98,7 @@ 'gc': 'boehm', 'backend': 'c', + 'stackless': False, 'batch': False, 'text': False, Modified: pypy/branch/hl-backend/pypy/translator/js/arraynode.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/arraynode.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/arraynode.py Fri Oct 14 17:44:56 2005 @@ -39,14 +39,14 @@ # ______________________________________________________________________ # entry points from genllvm # - def writedatatypedecl(self, codewriter): - codewriter.arraydef(self.ref, - 'int', - self.db.repr_type(self.arraytype)) - - def writedecl(self, codewriter): - # declaration for constructor - codewriter.declare(self.constructor_decl) + #def writedatatypedecl(self, codewriter): + # codewriter.arraydef(self.ref, + # 'int', + # self.db.repr_type(self.arraytype)) + + #def writedecl(self, codewriter): + # # declaration for constructor + # codewriter.declare(self.constructor_decl) class VoidArrayTypeNode(LLVMNode): @@ -58,9 +58,9 @@ self.array = array self.ref = "arraytype_Void" - def writedatatypedecl(self, codewriter): - td = "%s = type { int }" % self.ref - codewriter.append(td) + #def writedatatypedecl(self, codewriter): + # td = "%s = type { int }" % self.ref + # codewriter.append(td) class ArrayNode(ConstantLLVMNode): """ An arraynode. Elements can be @@ -91,6 +91,12 @@ if p is not None: self.db.prepare_constant(lltype.typeOf(p), p) + def writedecl(self, codewriter): + if self.arraytype is lltype.Char: #or use seperate nodetype + codewriter.declare(self.ref + ' = new String()') + else: + codewriter.declare(self.ref + ' = new Array()') + def get_length(self): """ returns logical length of array """ items = self.value.items @@ -109,21 +115,22 @@ return "{ int, [%s x %s] }" % (arraylen, typeval) def get_ref(self): + return self.ref #typeval = self.db.repr_type(lltype.typeOf(self.value)) #ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), self.ref, typeval) - p, c = lltype.parentlink(self.value) - assert p is None, "child arrays are NOT needed by rtyper" + #p, c = lltype.parentlink(self.value) + #assert p is None, "child arrays are NOT needed by rtyper" #return ref - return self.ref def get_pbcref(self, toptr): - ref = self.ref - p, c = lltype.parentlink(self.value) - assert p is None, "child arrays are NOT needed by rtyper" - - fromptr = "%s*" % self.get_typerepr() - ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) - return ref + return self.ref + #ref = self.ref + #p, c = lltype.parentlink(self.value) + #assert p is None, "child arrays are NOT needed by rtyper" + # + #fromptr = "%s*" % self.get_typerepr() + #ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) + #return ref def get_childref(self, index): return "getelementptr(%s* %s, int 0, uint 1, int %s)" %( @@ -156,9 +163,6 @@ 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: if ord(c) in StrArrayNode.printables: @@ -166,7 +170,7 @@ else: s.append("\\%02x" % ord(c)) - r = 'c"%s"' % "".join(s) + r = '"%s"' % "".join(s) return item_length, r class VoidArrayNode(ConstantLLVMNode): Modified: pypy/branch/hl-backend/pypy/translator/js/codewriter.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/codewriter.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/codewriter.py Fri Oct 14 17:44:56 2005 @@ -11,13 +11,18 @@ def __init__(self, f, js): self.f = f self.js = js + self._skip_closeblock = False def append(self, line, indentation_level=4): if indentation_level: s = self.tabstring * indentation_level else: s = '' - self.f.write(s + line + '\n') + if not line or line[-1] in '{:};' or line.lstrip()[:2] == '//': + eol = '\n' + else: + eol = ';\n' + self.f.write(s + line + eol) def comment(self, line, indentation_level=4): self.append("// " + line, indentation_level) @@ -30,10 +35,15 @@ def label(self, name): self.append("case %d:" % name, 3) - openblock = label + + def openblock(self, name): + self.append("case %d:" % name, 3) + self._currentblock = name def closeblock(self): - self.append('continue') + if not self._skip_closeblock: + self.append('break') + self._skip_closeblock = False def globalinstance(self, name, typeanddata): #self.append('%s = %s' % (name, typeanddata[1:].split('{')[1][:-1]), 0) @@ -44,32 +54,61 @@ self.llvm(line, 0) def structdef(self, name, typereprs): - self.llvm("%s = type { %s }" %(name, ", ".join(typereprs)), 0) + #self.llvm("%s = type { %s }" %(name, ", ".join(typereprs)), 0) + pass def arraydef(self, name, lentype, typerepr): - self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr), 0) + #self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr), 0) + pass def funcdef(self, name, rettyperepr, argtypereprs): - self.llvm("%s = type %s (%s)" % (name, rettyperepr, - ", ".join(argtypereprs)), 0) + #self.llvm("%s = type %s (%s)" % (name, rettyperepr, + # ", ".join(argtypereprs)), 0) + pass def declare(self, decl): - #self.llvm("declare %s" % decl, 0) - pass + self.append(decl, 0) def startimpl(self): #self.llvm("implementation", 0) pass - def br_uncond(self, blockname): - self.append('prevblock = block') - self.append('block = %d' % blockname) - #self.llvm("br label %s" %(blockname,)) - - def br(self, cond, blockname_false, blockname_true): - self.append('prevblock = block') - self.append('block = %s ? %d : %d' % (cond, blockname_true, blockname_false)) - #self.llvm("br bool %s, label %s, label %s" % (cond, blockname_true, blockname_false)) + def _goto_block(self, block, indentation_level=4): + if block == self._currentblock + 1: + self._skip_closeblock = True + else: + self.append('block = ' + str(block), indentation_level) + self.append('break', indentation_level) + + def _phi(self, targetblock, exit, indentation_level=4): + #self.comment('target.inputargs=%s, args=%s, targetblock=%d' % (exit.target.inputargs, exit.args, targetblock), indentation_level) + for i, exitarg in enumerate(exit.args): + dest = str(exit.target.inputargs[i]) + #src = str(exitarg) + src = str(self.js.db.repr_arg(exitarg)) + if src == 'False': + src = 'false' + elif src == 'True': + src = 'true' + elif src == 'None': + src = 'undefined' + if dest != src: + self.append('%s = %s' % (dest, src), indentation_level) + + def br_uncond(self, block, exit): + self._phi(block, exit) + self._goto_block(block) + self._skip_closeblock = True + + def br(self, cond, block_false, exit_false, block_true, exit_true): + self.append('if (%s) {' % cond) + self._phi(block_true, exit_true, 5) + self._goto_block(block_true, 5) + self.append('} else {') + self._phi(block_false, exit_false, 5) + self._goto_block(block_false, 5) + self.append('}') + self._skip_closeblock = True def switch(self, intty, cond, defaultdest, value_label): labels = '' @@ -84,6 +123,10 @@ self.blocks = blocks usedvars = {} #XXX could probably be limited to inputvars for block in blocks: + if block != blocks[0]: #don't double startblock inputargs + for inputarg in block.inputargs: + targetvar = self.js.db.repr_arg(inputarg) + usedvars[targetvar] = True for op in block.operations: targetvar = self.js.db.repr_arg(op.result) usedvars[targetvar] = True @@ -91,49 +134,20 @@ self.append("function %s {" % self.decl, 0) if usedvars: self.append("var %s" % ', '.join(usedvars.keys()), 1) - self.append("var block = 0", 1) - self.append("while (block != undefined) {", 1) + self.append("for (var block = 0;;) {", 1) self.append("switch (block) {", 2) def closefunc(self): - self.append("} // end of switch (block)", 2) - self.append("} // end of while (block != undefined)", 1) - self.append("} // end of function %s" % self.decl, 0) + self.append("}", 2) + self.append("}", 1) + self.append("};", 0) def ret(self, type_, ref): if type_ == 'void': self.append("return") else: self.append("return " + ref) - - def phi(self, targetvar, type_, refs, blocknames): - assert refs and len(refs) == len(blocknames), "phi node requires blocks" - #mergelist = ", ".join( - # ["[%s, %s]" % item - # for item in zip(refs, blocknames)]) - #s = "%s = phi %s %s" % (targetvar, type_, mergelist) - #self.llvm(s) - all_refs_identical = True - for ref in refs: - if ref != refs[0]: - all_refs_identical = False - break - if all_refs_identical: - if targetvar != refs[0]: - self.append('%s = %s' % (targetvar, refs[0])) - else: - if len(blocknames) == 1: - self.append('%s = %s' % (targetvar, refs[i])) - else: - n = 0 - for i, blockname in enumerate(blocknames): - if targetvar != refs[i]: - if n > 0: - s = 'else ' - else: - s = '' - self.append('%sif (prevblock == %d) %s = %s' % (s, blockname, targetvar, refs[i])) - n += 1 + self._skip_closeblock = True def binaryop(self, name, targetvar, type_, ref1, ref2): self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) @@ -155,10 +169,10 @@ self.append('%s = %s(%s)' % (targetvar, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): - self.comment('codewriter cast 1 targettype=%(targettype)s, targetvar=%(targetvar)s, fromtype=%(fromtype)s, fromvar=%(fromvar)s' % locals()) + #self.comment('codewriter cast 1 targettype=%(targettype)s, targetvar=%(targetvar)s, fromtype=%(fromtype)s, fromvar=%(fromvar)s' % locals()) if fromtype == 'void' and targettype == 'void': return - self.comment('codewriter cast 2') + #self.comment('codewriter cast 2') if targettype == fromtype: self.append("%(targetvar)s = %(fromvar)s" % locals()) elif targettype in ('int','uint',): Modified: pypy/branch/hl-backend/pypy/translator/js/database.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/database.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/database.py Fri Oct 14 17:44:56 2005 @@ -213,7 +213,7 @@ return self.obj2node.itervalues() # __________________________________________________________ - # Representing variables and constants in LLVM source code + # Representing variables and constants in Javascript source code def repr_arg(self, arg): if isinstance(arg, Constant): @@ -242,7 +242,7 @@ if isinstance(type_, lltype.Primitive): return self.primitives[type_] elif isinstance(type_, lltype.Ptr): - return self.repr_type(type_.TO) + '*' + return '' #self.repr_type(type_.TO) + 'XXX*' else: raise TypeError("cannot represent %r" %(type_,)) @@ -260,7 +260,8 @@ type_ = lltype.typeOf(value) if isinstance(type_, lltype.Primitive): repr = self.primitive_to_str(type_, value) - return None, "%s %s" % (self.repr_type(type_), repr) + return None, repr + #return None, "%s %s" % (self.repr_type(type_), repr) elif isinstance(type_, lltype.Ptr): toptr = self.repr_type(type_) @@ -333,13 +334,13 @@ # __________________________________________________________ # 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_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 get_childref(self, parent, child): node = self.obj2node[parent] Modified: pypy/branch/hl-backend/pypy/translator/js/funcnode.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/funcnode.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/funcnode.py Fri Oct 14 17:44:56 2005 @@ -22,7 +22,7 @@ self.db = db assert isinstance(type_, lltype.FuncType) self.type_ = type_ - self.ref = self.make_ref('%functiontype', '') + self.ref = self.make_ref('functiontype', '') def __str__(self): return "" % self.ref @@ -31,10 +31,10 @@ self.db.prepare_type(self.type_.RESULT) self.db.prepare_type_multi(self.type_._trueargs()) - def writedatatypedecl(self, codewriter): - 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) + #def writedatatypedecl(self, codewriter): + # 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): __slots__ = "db value ref graph blockindex".split() @@ -42,14 +42,15 @@ def __init__(self, db, value): self.db = db self.value = value - self.ref = self.make_ref('pypy_', value.graph.name) + pypy_prefix = '' #pypy_ + self.ref = self.make_ref(pypy_prefix, value.graph.name) self.graph = value.graph self.db.genllvm.exceptionpolicy.transform(self.db.translator, self.graph) #remove_exception_mallocs(self.db.translator, self.graph, self.ref) #merge_mallocs(self.db.translator, self.graph, self.ref) - remove_double_links(self.db.translator, self.graph) + #remove_double_links(self.db.translator, self.graph) def __str__(self): return "" %(self.ref,) @@ -76,8 +77,8 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedecl(self, codewriter): - codewriter.declare(self.getdecl()) + #def writedecl(self, codewriter): + # codewriter.declare(self.getdecl()) def writeimpl(self, codewriter): graph = self.graph @@ -145,30 +146,30 @@ return self.ref + "(%s)" % ", ".join(inputargs) def write_block(self, codewriter, block): - self.write_block_phi_nodes(codewriter, block) + #self.write_block_phi_nodes(codewriter, block) self.write_block_operations(codewriter, block) self.write_block_branches(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) - inputargtypes = self.db.repr_arg_type_multi(block.inputargs) - for i, (arg, type_) in enumerate(zip(inputargs, inputargtypes)): - names = self.db.repr_arg_multi([link.args[i] for link in entrylinks]) - blocknames = [self.blockindex[link.prevblock] for link in entrylinks] - for i, link in enumerate(entrylinks): #XXX refactor into a transformation - if link.prevblock.exitswitch == Constant(last_exception) and \ - link.prevblock.exits[0].target != block: - blocknames[i] += '_exception_found_branchto_' + self.blockindex[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": - codewriter.phi(arg, type_, names, blocknames) + #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) + # inputargtypes = self.db.repr_arg_type_multi(block.inputargs) + # for i, (arg, type_) in enumerate(zip(inputargs, inputargtypes)): + # names = self.db.repr_arg_multi([link.args[i] for link in entrylinks]) + # blocknames = [self.blockindex[link.prevblock] for link in entrylinks] + # for i, link in enumerate(entrylinks): #XXX refactor into a transformation + # if link.prevblock.exitswitch == Constant(last_exception) and \ + # link.prevblock.exits[0].target != block: + # blocknames[i] += '_exception_found_branchto_' + self.blockindex[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": + # 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) @@ -176,11 +177,12 @@ #codewriter.comment('FuncNode(ConstantLLVMNode) *last_exception* write_block_branches @%s@' % str(block.exits)) return if len(block.exits) == 1: - codewriter.br_uncond(self.blockindex[block.exits[0].target]) + codewriter.br_uncond(self.blockindex[block.exits[0].target], block.exits[0]) elif len(block.exits) == 2: cond = self.db.repr_arg(block.exitswitch) - codewriter.br(cond, self.blockindex[block.exits[0].target], - self.blockindex[block.exits[1].target]) + codewriter.br(cond, + self.blockindex[block.exits[0].target], block.exits[0], + self.blockindex[block.exits[1].target], block.exits[1]) def write_block_operations(self, codewriter, block): opwriter = OpWriter(self.db, codewriter, self, block) @@ -212,7 +214,7 @@ def write_returnblock(self, codewriter, block): assert len(block.inputargs) == 1 - self.write_block_phi_nodes(codewriter, block) + #self.write_block_phi_nodes(codewriter, block) inputargtype = self.db.repr_arg_type(block.inputargs[0]) inputarg = self.db.repr_arg(block.inputargs[0]) codewriter.ret(inputargtype, inputarg) Modified: pypy/branch/hl-backend/pypy/translator/js/js.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/js.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/js.py Fri Oct 14 17:44:56 2005 @@ -4,6 +4,7 @@ http://webreference.com/programming/javascript/ http://mochikit.com/ http://www.mozilla.org/js/spidermonkey/ + svn co http://codespeak.net/svn/kupu/trunk/ecmaunit ''' #import os @@ -77,7 +78,7 @@ # codewriter.comment("External Function Declarations") # codewriter.append(llexterns_header) - codewriter.comment("Type Declarations", 0) + #codewriter.comment("Type Declarations", 0) #for c_name, obj in extern_decls: # if isinstance(obj, lltype.LowLevelType): # if isinstance(obj, lltype.Ptr): @@ -85,33 +86,33 @@ # l = "%%%s = type %s" % (c_name, self.db.repr_type(obj)) # codewriter.append(l) + codewriter.comment("Function Implementation", 0) + for typ_decl in self.db.getnodes(): + typ_decl.writeimpl(codewriter) + + codewriter.comment("Forward Declarations", 0) + #for typ_decl in self.db.getnodes(): + # typ_decl.writedatatypedecl(codewriter) for typ_decl in self.db.getnodes(): - typ_decl.writedatatypedecl(codewriter) + typ_decl.writedecl(codewriter) codewriter.comment("Global Data", 0) for typ_decl in self.db.getnodes(): typ_decl.writeglobalconstants(codewriter) - codewriter.comment("Function Prototypes", 0) + #codewriter.comment("Function Prototypes", 0) #codewriter.append(extdeclarations) #codewriter.append(self.gcpolicy.declarations()) - for typ_decl in self.db.getnodes(): - typ_decl.writedecl(codewriter) - - codewriter.comment("Function Implementation", 0) - codewriter.startimpl() - - for typ_decl in self.db.getnodes(): - typ_decl.writeimpl(codewriter) + pypy_prefix = '' #pypy_ #codewriter.append(self.exceptionpolicy.llvmcode(self.entrynode)) # ## XXX we need to create our own main() that calls the actual entry_point function - #if entryfunc_name == 'pypy_entry_point': #XXX just to get on with translate_pypy + #if entryfunc_name == pypy_prefix + '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 + #elif entryfunc_name == pypy_prefix + 'main_noargs': #XXX just to get on with bpnn & richards # extfuncnode.ExternalFuncNode.used_external_functions['%main_noargs'] = True # #for f in support_functions: @@ -134,7 +135,7 @@ graph = self.db.obj2node[entry_point].graph startblock = graph.startblock args = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)]) - self.wrappertemplate = "load('%s'); print(pypy_%s(%%s))" % (self.filename, graph.name) + self.wrappertemplate = "load('%s'); print(%s%s(%%s))" % (self.filename, pypy_prefix, graph.name) #codewriter.newline() #codewriter.comment("Wrapper code for the Javascript CLI", 0) Modified: pypy/branch/hl-backend/pypy/translator/js/node.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/node.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/node.py Fri Oct 14 17:44:56 2005 @@ -32,10 +32,10 @@ pass # __________________ before "implementation" ____________________ - def writedatatypedecl(self, codewriter): - """ write out declare names of data types - (structs/arrays/function pointers) - """ + #def writedatatypedecl(self, codewriter): + # """ write out declare names of data types + # (structs/arrays/function pointers) + # """ def writeglobalconstants(self, codewriter): """ write out global values. """ Modified: pypy/branch/hl-backend/pypy/translator/js/opaquenode.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/opaquenode.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/opaquenode.py Fri Oct 14 17:44:56 2005 @@ -7,7 +7,7 @@ assert isinstance(opaquetype, lltype.OpaqueType) self.db = db self.opaquetype = opaquetype - self.ref = "%%opaquetype.%s" % (opaquetype.tag) + self.ref = "opaquetype." + opaquetype.tag def __str__(self): return "" %(self.ref,) @@ -15,9 +15,9 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedatatypedecl(self, codewriter): - # XXX Dummy - not sure what what we want - codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *']) + #def writedatatypedecl(self, codewriter): + # # XXX Dummy - not sure what what we want + # codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *']) class OpaqueNode(ConstantLLVMNode): Modified: pypy/branch/hl-backend/pypy/translator/js/opwriter.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/opwriter.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/opwriter.py Fri Oct 14 17:44:56 2005 @@ -212,7 +212,7 @@ 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]) - self.codewriter.comment(op.opname) + self.codewriter.comment('next line='+op.opname) self.codewriter.cast(targetvar, fromtype, fromvar, targettype) same_as = cast_primitive @@ -254,8 +254,8 @@ 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:]) - if self.db.is_function_ptr(op.result): - returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) + #if self.db.is_function_ptr(op.result): + # returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) self.codewriter.call(targetvar,returntype,functionref,argrefs,argtypes) def last_exception_type_ptr(self, op): @@ -297,8 +297,8 @@ block_label = self.node.blockindex[self.block] exc_label = block_label + '_exception_handling' - if self.db.is_function_ptr(op.result): #use longhand form - returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) + #if self.db.is_function_ptr(op.result): #use longhand form + # returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) self.codewriter.call(targetvar, returntype, functionref, argrefs, argtypes, none_label, exc_label) @@ -407,35 +407,27 @@ def getfield(self, op): tmpvar = self.db.repr_tmpvar() struct, structtype = self.db.repr_argwithtype(op.args[0]) - 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) + self.codewriter.append('%s = %s.%s' % (targetvar, struct, op.args[1].value)) #XXX move to codewriter else: self._skipped(op) def getsubstruct(self, op): struct, structtype = self.db.repr_argwithtype(op.args[0]) - index = self._getindexhelper(op.args[1].value, op.args[0].concretetype.TO) + #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" - self.codewriter.getelementptr(targetvar, structtype, - struct, ("uint", index)) + #targettype = self.db.repr_arg_type(op.result) + #assert targettype != "void" + self.codewriter.append('%s = %s.%s' % (targetvar, struct, op.args[1].value)) #XXX move to codewriter + #self.codewriter.getelementptr(targetvar, structtype, struct, ("uint", index)) def setfield(self, op): - tmpvar = self.db.repr_tmpvar() struct, structtype = self.db.repr_argwithtype(op.args[0]) - 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, - ("uint", index)) - self.codewriter.store(valuetype, valuevar, tmpvar) + self.codewriter.append('%s.%s = %s' % (struct, op.args[1].value, valuevar)) #XXX move to codewriter else: self._skipped(op) @@ -479,8 +471,9 @@ def getarraysize(self, op): array, arraytype = self.db.repr_argwithtype(op.args[0]) - tmpvar = self.db.repr_tmpvar() - self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 0)) + #tmpvar = self.db.repr_tmpvar() + #self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 0)) targetvar = self.db.repr_arg(op.result) - targettype = self.db.repr_arg_type(op.result) - self.codewriter.load(targetvar, targettype, tmpvar) + #targettype = self.db.repr_arg_type(op.result) + #self.codewriter.load(targetvar, targettype, tmpvar) + self.codewriter.append('%s = %s.length' % (targetvar, array)) #XXX move to codewriter Modified: pypy/branch/hl-backend/pypy/translator/js/structnode.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/structnode.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/structnode.py Fri Oct 14 17:44:56 2005 @@ -5,6 +5,11 @@ log = log.structnode +def _rename_reserved_keyword(name): + if name in 'if then else function for while witch continue break super int bool Array String Struct Number'.split(): + name += '_' + return name + class StructTypeNode(LLVMNode): __slots__ = "db struct ref name".split() @@ -32,9 +37,9 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedatatypedecl(self, codewriter): - fields_types = [self.db.repr_type(f) for f in self._fields()] - codewriter.structdef(self.ref, fields_types) + #def writedatatypedecl(self, codewriter): + # fields_types = [self.db.repr_type(f) for f in self._fields()] + # codewriter.structdef(self.ref, fields_types) class StructVarsizeTypeNode(StructTypeNode): __slots__ = "constructor_ref constructor_decl".split() @@ -53,9 +58,9 @@ # ______________________________________________________________________ # main entry points from genllvm - def writedecl(self, codewriter): - # declaration for constructor - codewriter.declare(self.constructor_decl) + #def writedecl(self, codewriter): + # # declaration for constructor + # codewriter.declare(self.constructor_decl) def writeimpl(self, codewriter): log.writeimpl(self.ref) @@ -83,7 +88,7 @@ self.db = db self.value = value self.structtype = self.value._TYPE - prefix = '%structinstance.' + prefix = 'structinstance_' name = str(value).split()[1] self.ref = self.make_ref(prefix, name) self._get_ref_cache = None @@ -112,24 +117,26 @@ p, c = lltype.parentlink(self.value) if p is not None: self.db.prepare_constant(lltype.typeOf(p), p) - + + def writedecl(self, codewriter): + codewriter.declare(self.ref + ' = new Object()') + def get_typerepr(self): return self.db.repr_type(self.structtype) def get_childref(self, index): - pos = 0 - found = False - for name in self.structtype._names_without_voids(): - if name == index: - 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(), - pos) + return self.get_ref() #XXX what to do with index? + #pos = 0 + #found = False + #for name in self.structtype._names_without_voids(): + # if name == index: + # found = True + # break + # pos += 1 + #return "getelementptr(%s* %s, int 0, uint %s)" %( + # self.get_typerepr(), + # self.get_ref(), + # pos) def get_ref(self): """ Returns a reference as used for operations in blocks. """ @@ -146,12 +153,20 @@ def get_pbcref(self, toptr): """ Returns a reference as used per pbc. """ return self.get_ref() - + def constantvalue(self): """ Returns the constant representation for this node. """ - values = self._getvalues() - all_values = ",\n ".join(values) - return "%s {\n %s\n }\n" % (self.get_typerepr(), all_values) + vars = [] + for i, value in enumerate(self._getvalues()): + name = self._get_types[i][0] + name = _rename_reserved_keyword(name) + var = (name, str(value)) + vars.append(var) + return "({%s})" % ", ".join(["%s:%s" % var for var in vars]) + + #values = self._getvalues() + #all_values = ",\n ".join(values) + #return "%s {\n %s\n }\n" % (self.get_typerepr(), all_values) class StructVarsizeNode(StructNode): @@ -206,22 +221,24 @@ return result def get_ref(self): - if self._get_ref_cache: - return self._get_ref_cache - ref = super(StructVarsizeNode, self).get_ref() - typeval = self.db.repr_type(lltype.typeOf(self.value)) - ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), - ref, - typeval) - self._get_ref_cache = ref - return ref + return self.ref + #if self._get_ref_cache: + # return self._get_ref_cache + #ref = super(StructVarsizeNode, self).get_ref() + #typeval = self.db.repr_type(lltype.typeOf(self.value)) + #ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), + # ref, + # typeval) + #self._get_ref_cache = ref + #return ref def get_pbcref(self, toptr): """ Returns a reference as used per pbc. """ - ref = self.ref - p, c = lltype.parentlink(self.value) - 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) - return ref + return self.ref + #ref = self.ref + #p, c = lltype.parentlink(self.value) + #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) + #return ref Modified: pypy/branch/hl-backend/pypy/translator/js/test/test_genllvm1.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/js/test/test_genllvm1.py (original) +++ pypy/branch/hl-backend/pypy/translator/js/test/test_genllvm1.py Fri Oct 14 17:44:56 2005 @@ -28,7 +28,7 @@ def test_ackermann(self): f = compile_function(llvmsnippet.ackermann, [int, int]) - for i in range(10): + for i in range(7): #>7 js error: too much recursion?!? assert f(0, i) == i + 1 assert f(1, i) == i + 2 assert f(2, i) == 2 * i + 3 Modified: pypy/branch/hl-backend/pypy/translator/llvm/build_llvm_module.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/llvm/build_llvm_module.py (original) +++ pypy/branch/hl-backend/pypy/translator/llvm/build_llvm_module.py Fri Oct 14 17:44:56 2005 @@ -82,13 +82,19 @@ use_gcc = True profile = False + cleanup = False + + if sys.platform == 'darwin': + gc_libs_path = '-L/sw/lib -ldl' + else: + gc_libs_path = '-static' cmds = ["llvm-as < %s.ll | opt %s -f -o %s.bc" % (b, OPTIMIZATION_SWITCHES, b)] if not use_gcc: cmds.append("llc %s %s.bc -f -o %s.s" % (genllvm.exceptionpolicy.llc_options(), b, b)) cmds.append("as %s.s -o %s.o" % (b, b)) if exe_name: - cmd = "gcc %s.o %s -lm -ldl -pipe -o %s" % (b, gc_libs, exe_name) + cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) cmds.append(cmd) object_files.append("%s.o" % b) else: @@ -100,13 +106,13 @@ else: cmd += ' -fomit-frame-pointer' cmds.append(cmd) - cmd = "gcc %s.o %s -lm -ldl -pipe -o %s" % (b, gc_libs, exe_name) + cmd = "gcc %s.o %s %s -lm -pipe -o %s" % (b, gc_libs_path, gc_libs, exe_name) if profile: cmd += ' -pg' cmds.append(cmd) source_files.append("%s.c" % b) - if exe_name and not profile: + if cleanup and exe_name and not profile: cmds.append('strip ' + exe_name) upx = os.popen('which upx').read() if upx: #compress file even further Modified: pypy/branch/hl-backend/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/llvm/externs2ll.py (original) +++ pypy/branch/hl-backend/pypy/translator/llvm/externs2ll.py Fri Oct 14 17:44:56 2005 @@ -1,4 +1,5 @@ import os +import sys import types import urllib @@ -11,10 +12,20 @@ def get_ll(ccode, function_names): + filename = str(udir.join("ccode.c")) + f = open(filename, "w") + f.write(ccode) + f.close() - # goto codespeak and compile our c code - request = urllib.urlencode({'ccode':ccode}) - llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() + if os.popen('which llvm-gcc').read(): #local llvm CFE available + #log('using local llvm-gcc') + plain = filename[:-2] + os.system("llvm-gcc -S %s.c -o %s.ll 2>&1" % (plain, plain)) + llcode = open(plain + '.ll').read() + else: #as fallback use remove CFE. XXX local and remote should be similar machines! + #log('falling back on remote llvm-gcc') + request = urllib.urlencode({'ccode':ccode}) # goto codespeak and compile our c code + llcode = urllib.urlopen('http://codespeak.net/pypy/llvm-gcc.cgi', request).read() # strip lines ll_lines = [] @@ -134,13 +145,14 @@ include_files.append(j(j(os.path.dirname(extfunc.__file__), "src"), f + ".h")) for f in include_files: - ccode.append(open(f).read()) + s = open(f).read() + if f.find('genexterns.c'): + if sys.platform == 'darwin': + python_h = '"/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3/Python.h"' + else: + python_h = '' + s = s.replace('__PYTHON_H__', python_h) + ccode.append(s) ccode = "".join(ccode) - if debug: - filename = udir.join("ccode.c") - f = open(str(filename), "w") - f.write(ccode) - f.close() - return get_ll(ccode, function_names + support_functions) Modified: pypy/branch/hl-backend/pypy/translator/llvm/gc.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/llvm/gc.py (original) +++ pypy/branch/hl-backend/pypy/translator/llvm/gc.py Fri Oct 14 17:44:56 2005 @@ -25,7 +25,8 @@ gcpolicy = gcpolicy or 'boehm' from os.path import exists - boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') + boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a') or \ + exists('/sw/lib/libgc.so') or exists('/sw/lib/libgc.a') if gcpolicy == 'boehm' and not boehm_on_path: log.gc.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc') gcpolicy = 'none' Modified: pypy/branch/hl-backend/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/branch/hl-backend/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/branch/hl-backend/pypy/translator/llvm/module/genexterns.c Fri Oct 14 17:44:56 2005 @@ -19,7 +19,9 @@ #include #include #include -#include + +//the placeholder in the next line gets replaced by the actual python.h path +#include __PYTHON_H__ // Do this manually from python :-( //#include "ll_os.h" Modified: pypy/branch/hl-backend/pypy/translator/transform.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/transform.py (original) +++ pypy/branch/hl-backend/pypy/translator/transform.py Fri Oct 14 17:44:56 2005 @@ -14,7 +14,7 @@ from pypy.translator.annrpython import CannotSimplify from pypy.annotation import model as annmodel from pypy.annotation.specialize import MemoTable - +from pypy.rpython.objectmodel import stack_check def checkgraphs(self, blocks): seen = {} @@ -187,6 +187,30 @@ else: op.opname = intern('call_specialcase') +def insert_stackcheck(ann): + from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles + edges = [] + for callposition, (caller, callee) in ann.translator.callgraph.items(): + edge = Edge(caller, callee) + edge.callposition = callposition + edges.append(edge) + edgedict = make_edge_dict(edges) + for edge in break_cycles(edgedict, edgedict): + caller = edge.source + _, _, call_tag = edge.callposition + if call_tag: + _, caller_block, _ = call_tag + else: + ann.warning("cycle detected but no information on where to insert " + "stack_check()") + continue + # caller block found, insert stack_check() + v = Variable() + # push annotation on v + ann.setbinding(v, annmodel.SomeImpossibleValue()) + unwind_op = SpaceOperation('simple_call', [Constant(stack_check)], v) + caller_block.operations.insert(0, unwind_op) + default_extra_passes = [ transform_specialization, transform_allocate, Modified: pypy/branch/hl-backend/pypy/translator/translator.py ============================================================================== --- pypy/branch/hl-backend/pypy/translator/translator.py (original) +++ pypy/branch/hl-backend/pypy/translator/translator.py Fri Oct 14 17:44:56 2005 @@ -329,11 +329,11 @@ self.frozen = True return genllvm.genllvm(self, really_compile=really_compile, standalone=standalone, optimize=optimize, exe_name=exe_name, gcpolicy=gcpolicy) - def asmcompile(self, processor='ppc'): + def asmcompile(self, processor='virt'): from pypy.translator.asm import genasm - assert processor == 'ppc', 'only ppc asm-generation supported for now' + assert processor in ['ppc', 'virt', 'virtfinite'] assert self.rtyper is not None, 'must specialize' - return genasm.genasm(self) + return genasm.genasm(self, processor) def call(self, *args): """Calls underlying Python function.""" From boria at codespeak.net Fri Oct 14 17:50:54 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 17:50:54 +0200 (CEST) Subject: [pypy-svn] r18566 - pypy/branch/hl-backend/pypy/rpython/l3interp Message-ID: <20051014155054.4DC1227B58@code1.codespeak.net> Author: boria Date: Fri Oct 14 17:50:54 2005 New Revision: 18566 Removed: pypy/branch/hl-backend/pypy/rpython/l3interp/ Log: * Removed l3interp/. From boria at codespeak.net Fri Oct 14 17:52:34 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 17:52:34 +0200 (CEST) Subject: [pypy-svn] r18567 - pypy/branch/hl-backend/pypy/rpython/l3interp Message-ID: <20051014155234.D8DB827B58@code1.codespeak.net> Author: boria Date: Fri Oct 14 17:52:34 2005 New Revision: 18567 Added: pypy/branch/hl-backend/pypy/rpython/l3interp/ - copied from r18566, pypy/dist/pypy/rpython/l3interp/ Log: * Added l3interp/ from trunk. From boria at codespeak.net Fri Oct 14 17:55:09 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 17:55:09 +0200 (CEST) Subject: [pypy-svn] r18568 - pypy/dist/pypy/rpython Message-ID: <20051014155509.5242827B5C@code1.codespeak.net> Author: boria Date: Fri Oct 14 17:55:09 2005 New Revision: 18568 Removed: pypy/dist/pypy/rpython/ Log: * Removing rpython/ from trunk. From boria at codespeak.net Fri Oct 14 17:55:47 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 17:55:47 +0200 (CEST) Subject: [pypy-svn] r18569 - pypy/dist/pypy/rpython Message-ID: <20051014155547.4551227B5E@code1.codespeak.net> Author: boria Date: Fri Oct 14 17:55:47 2005 New Revision: 18569 Added: pypy/dist/pypy/rpython/ - copied from r18568, pypy/branch/hl-backend/pypy/rpython/ Log: * Adding rpython/ from hl-backend branch into trunk. From afa at codespeak.net Fri Oct 14 17:58:46 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 14 Oct 2005 17:58:46 +0200 (CEST) Subject: [pypy-svn] r18570 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051014155846.86A5127B62@code1.codespeak.net> Author: afa Date: Fri Oct 14 17:58:43 2005 New Revision: 18570 Modified: pypy/dist/pypy/module/_socket/interp_socket.py (contents, props changed) pypy/dist/pypy/module/_socket/test/test_socket2.py Log: valentino, afa: added socket.getaddrinfo Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Fri Oct 14 17:58:43 2005 @@ -1,175 +1,205 @@ - -import socket -from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import ObjSpace, W_Root, NoneNotWrapped - -def gethostname(space): - """gethostname() -> string - - Return the current host name. - """ - return space.wrap(socket.gethostname()) -gethostname.unwrap_spec = [ObjSpace] - -def gethostbyname(space, name): - """gethostbyname(host) -> address - - Return the IP address (a string of the form '255.255.255.255') for a host. - """ - return space.wrap(socket.gethostbyname(name)) -gethostbyname.unwrap_spec = [ObjSpace, str] - -def gethostbyname_ex(space, name): - """gethostbyname_ex(host) -> (name, aliaslist, addresslist) - - Return the true host name, a list of aliases, and a list of IP addresses, - for a host. The host argument is a string giving a host name or IP number. - """ - return space.wrap(socket.gethostbyname_ex(name)) -gethostbyname_ex.unwrap_spec = [ObjSpace, str] - -def gethostbyaddr(space, ip_num): - """gethostbyaddr(host) -> (name, aliaslist, addresslist) - - Return the true host name, a list of aliases, and a list of IP addresses, - for a host. The host argument is a string giving a host name or IP number. - """ - return space.wrap(socket.gethostbyaddr(ip_num)) -gethostbyaddr.unwrap_spec = [ObjSpace, str] - -def getservbyname(space, name, w_proto=NoneNotWrapped): - """getservbyname(servicename[, protocolname]) -> integer - - Return a port number from a service name and protocol name. - The optional protocol name, if given, should be 'tcp' or 'udp', - otherwise any protocol will match. - """ - if w_proto is None: - return space.wrap(socket.getservbyname(name)) - else: - return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) -getservbyname.unwrap_spec = [ObjSpace, str, W_Root] - -def getservbyport(space, port, w_proto=NoneNotWrapped): - """getservbyport(port[, protocolname]) -> string - - Return the service name from a port number and protocol name. - The optional protocol name, if given, should be 'tcp' or 'udp', - otherwise any protocol will match. - """ - if w_proto is None: - return space.wrap(socket.getservbyport(port)) - else: - return space.wrap(socket.getservbyport(port, space.str_w(w_proto))) -getservbyport.unwrap_spec = [ObjSpace, int, W_Root] - -def getprotobyname(space, name): - """getprotobyname(name) -> integer - - Return the protocol number for the named protocol. (Rarely used.) - """ - return space.wrap(socket.getprotobyname(name)) -getprotobyname.unwrap_spec = [ObjSpace, str] - -def fromfd(space, fd, family, type, w_proto=NoneNotWrapped): - """fromfd(fd, family, type[, proto]) -> socket object - - Create a socket object from the given file descriptor. - The remaining arguments are the same as for socket(). - """ - if w_proto is None: - return space.wrap(socket.fromfd(fd, family, type)) - else: - return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto))) -fromfd.unwrap_spec = [ObjSpace, int, int, int, W_Root] - -def socketpair(space, w_family=NoneNotWrapped, w_type=NoneNotWrapped, w_proto=NoneNotWrapped): - """socketpair([family[, type[, proto]]]) -> (socket object, socket object) - - Create a pair of socket objects from the sockets returned by the platform - socketpair() function. - The arguments are the same as for socket() except the default family is - AF_UNIX if defined on the platform; otherwise, the default is AF_INET. - """ - if w_family is None: - return space.wrap(socket.socketpair()) - elif w_type is None: - return space.wrap(socket.socketpair(space.int_w(w_family))) - elif w_proto is None: - return space.wrap(socket.socketpair(space.int_w(w_family), - space.int_w(w_type))) - else: - return space.wrap(socket.socketpair(space.int_w(w_family), - space.int_w(w_type), - space.int_w(w_proto))) -socketpair.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root] - -def ntohs(space, x): - """ntohs(integer) -> integer - - Convert a 16-bit integer from network to host byte order. - """ - return space.wrap(socket.ntohs(x)) -ntohs.unwrap_spec = [ObjSpace, int] - -def ntohl(space, x): - """ntohl(integer) -> integer - - Convert a 32-bit integer from network to host byte order. - """ - return space.wrap(socket.ntohl(x)) -ntohl.unwrap_spec = [ObjSpace, int] - -def htons(space, x): - """htons(integer) -> integer - - Convert a 16-bit integer from host to network byte order. - """ - return space.wrap(socket.htons(x)) -htons.unwrap_spec = [ObjSpace, int] - -def htonl(space, x): - """htonl(integer) -> integer - - Convert a 32-bit integer from host to network byte order. - """ - return space.wrap(socket.htonl(x)) -htonl.unwrap_spec = [ObjSpace, int] - -def inet_aton(space, ip): - """inet_aton(string) -> packed 32-bit IP representation - - Convert an IP address in string format (123.45.67.89) to the 32-bit packed - binary format used in low-level network functions. - """ - return space.wrap(socket.inet_aton(ip)) -inet_aton.unwrap_spec = [ObjSpace, str] - -def inet_ntoa(space, packed): - """inet_ntoa(packed_ip) -> ip_address_string - - Convert an IP address from 32-bit packed binary format to string format - """ - return space.wrap(socket.inet_ntoa(packed)) -inet_ntoa.unwrap_spec = [ObjSpace, str] - -def inet_pton(space, af, ip): - """inet_pton(af, ip) -> packed IP address string - - Convert an IP address from string format to a packed string suitable - for use with low-level network functions. - """ - return space.wrap(socket.inet_pton(af, ip)) -inet_pton.unwrap_spec = [ObjSpace, int, str] - -def inet_ntop(space, af, packed): - """inet_ntop(af, packed_ip) -> string formatted IP address - - Convert a packed IP address of the given family to string format. - """ - return space.wrap(socket.inet_ntop(af, packed)) -inet_ntop.unwrap_spec = [ObjSpace, int, str] - - -# getaddrinfo getnameinfo -# getdefaulttimeout setdefaulttimeout + +import socket +from pypy.interpreter.error import OperationError +from pypy.interpreter.gateway import W_Root +from pypy.interpreter.gateway import ObjSpace, NoneNotWrapped + +def gethostname(space): + """gethostname() -> string + + Return the current host name. + """ + return space.wrap(socket.gethostname()) +gethostname.unwrap_spec = [ObjSpace] + +def gethostbyname(space, name): + """gethostbyname(host) -> address + + Return the IP address (a string of the form '255.255.255.255') for a host. + """ + return space.wrap(socket.gethostbyname(name)) +gethostbyname.unwrap_spec = [ObjSpace, str] + +def gethostbyname_ex(space, name): + """gethostbyname_ex(host) -> (name, aliaslist, addresslist) + + Return the true host name, a list of aliases, and a list of IP addresses, + for a host. The host argument is a string giving a host name or IP number. + """ + return space.wrap(socket.gethostbyname_ex(name)) +gethostbyname_ex.unwrap_spec = [ObjSpace, str] + +def gethostbyaddr(space, ip_num): + """gethostbyaddr(host) -> (name, aliaslist, addresslist) + + Return the true host name, a list of aliases, and a list of IP addresses, + for a host. The host argument is a string giving a host name or IP number. + """ + return space.wrap(socket.gethostbyaddr(ip_num)) +gethostbyaddr.unwrap_spec = [ObjSpace, str] + +def getservbyname(space, name, w_proto=NoneNotWrapped): + """getservbyname(servicename[, protocolname]) -> integer + + Return a port number from a service name and protocol name. + The optional protocol name, if given, should be 'tcp' or 'udp', + otherwise any protocol will match. + """ + if w_proto is None: + return space.wrap(socket.getservbyname(name)) + else: + return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) +getservbyname.unwrap_spec = [ObjSpace, str, W_Root] + +def getservbyport(space, port, w_proto=NoneNotWrapped): + """getservbyport(port[, protocolname]) -> string + + Return the service name from a port number and protocol name. + The optional protocol name, if given, should be 'tcp' or 'udp', + otherwise any protocol will match. + """ + if w_proto is None: + return space.wrap(socket.getservbyport(port)) + else: + return space.wrap(socket.getservbyport(port, space.str_w(w_proto))) +getservbyport.unwrap_spec = [ObjSpace, int, W_Root] + +def getprotobyname(space, name): + """getprotobyname(name) -> integer + + Return the protocol number for the named protocol. (Rarely used.) + """ + return space.wrap(socket.getprotobyname(name)) +getprotobyname.unwrap_spec = [ObjSpace, str] + +def fromfd(space, fd, family, type, w_proto=NoneNotWrapped): + """fromfd(fd, family, type[, proto]) -> socket object + + Create a socket object from the given file descriptor. + The remaining arguments are the same as for socket(). + """ + if w_proto is None: + return space.wrap(socket.fromfd(fd, family, type)) + else: + return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto))) +fromfd.unwrap_spec = [ObjSpace, int, int, int, W_Root] + +def socketpair(space, w_family=NoneNotWrapped, w_type=NoneNotWrapped, w_proto=NoneNotWrapped): + """socketpair([family[, type[, proto]]]) -> (socket object, socket object) + + Create a pair of socket objects from the sockets returned by the platform + socketpair() function. + The arguments are the same as for socket() except the default family is + AF_UNIX if defined on the platform; otherwise, the default is AF_INET. + """ + if w_family is None: + return space.wrap(socket.socketpair()) + elif w_type is None: + return space.wrap(socket.socketpair(space.int_w(w_family))) + elif w_proto is None: + return space.wrap(socket.socketpair(space.int_w(w_family), + space.int_w(w_type))) + else: + return space.wrap(socket.socketpair(space.int_w(w_family), + space.int_w(w_type), + space.int_w(w_proto))) +socketpair.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root] + +def ntohs(space, x): + """ntohs(integer) -> integer + + Convert a 16-bit integer from network to host byte order. + """ + return space.wrap(socket.ntohs(x)) +ntohs.unwrap_spec = [ObjSpace, int] + +def ntohl(space, x): + """ntohl(integer) -> integer + + Convert a 32-bit integer from network to host byte order. + """ + return space.wrap(socket.ntohl(x)) +ntohl.unwrap_spec = [ObjSpace, int] + +def htons(space, x): + """htons(integer) -> integer + + Convert a 16-bit integer from host to network byte order. + """ + return space.wrap(socket.htons(x)) +htons.unwrap_spec = [ObjSpace, int] + +def htonl(space, x): + """htonl(integer) -> integer + + Convert a 32-bit integer from host to network byte order. + """ + return space.wrap(socket.htonl(x)) +htonl.unwrap_spec = [ObjSpace, int] + +def inet_aton(space, ip): + """inet_aton(string) -> packed 32-bit IP representation + + Convert an IP address in string format (123.45.67.89) to the 32-bit packed + binary format used in low-level network functions. + """ + return space.wrap(socket.inet_aton(ip)) +inet_aton.unwrap_spec = [ObjSpace, str] + +def inet_ntoa(space, packed): + """inet_ntoa(packed_ip) -> ip_address_string + + Convert an IP address from 32-bit packed binary format to string format + """ + return space.wrap(socket.inet_ntoa(packed)) +inet_ntoa.unwrap_spec = [ObjSpace, str] + +def inet_pton(space, af, ip): + """inet_pton(af, ip) -> packed IP address string + + Convert an IP address from string format to a packed string suitable + for use with low-level network functions. + """ + return space.wrap(socket.inet_pton(af, ip)) +inet_pton.unwrap_spec = [ObjSpace, int, str] + +def inet_ntop(space, af, packed): + """inet_ntop(af, packed_ip) -> string formatted IP address + + Convert a packed IP address of the given family to string format. + """ + return space.wrap(socket.inet_ntop(af, packed)) +inet_ntop.unwrap_spec = [ObjSpace, int, str] + +def getaddrinfo(space, w_host, w_port, w_family=NoneNotWrapped, + w_socktype=None, w_proto=None, + w_flags=None): + """getaddrinfo(host, port [, family, socktype, proto, flags]) + -> list of (family, socktype, proto, canonname, sockaddr) + + Resolve host and port into addrinfo struct. + """ + if space.is_true(space.isinstance(w_host, space.w_unicode)): + w_host = space.call_method(w_host, "encode", space.wrap("idna")) + host = space.unwrap(w_host) + + if space.is_true(space.isinstance(w_port, space.w_int)): + port = str(space.int_w(w_port)) + else: + port = space.str_w(w_port) + + if w_family is None: + return space.wrap(socket.getaddrinfo(host, port)) + else: + family = space.int_w(w_family) + socktype = space.int_w(w_socktype) + proto = space.int_w(w_proto) + flags = space.int_w(w_flags) + return space.wrap(socket.getaddrinfo(host, port, family, socktype, proto, flags)) +getaddrinfo.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root, W_Root, W_Root, W_Root] + + + + +# getaddrinfo getnameinfo +# getdefaulttimeout setdefaulttimeout Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Fri Oct 14 17:58:43 2005 @@ -141,3 +141,24 @@ res = space.appexec([w_socket], "(_socket): return _socket.has_ipv6") assert space.unwrap(res) == socket.has_ipv6 +def test_getaddrinfo(): + host = "localhost" + port = 25 + info = socket.getaddrinfo(host, port) + w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], + "(_socket, host, port): return _socket.getaddrinfo(host, port)") + assert space.unwrap(w_l) == info + w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port), space.wrap(0)], + """(_socket, host, port, family): + try: + return _socket.getaddrinfo(host, port, family) + except TypeError: # arguments are missing + return [1] + """) + assert space.unwrap(w_l) == [1] + py.test.skip("Too long...") + w_l = space.appexec([w_socket, space.wrap(unicode(host)), space.wrap(port)], + "(_socket, host, port): return _socket.getaddrinfo(host, port)") + assert space.unwrap(w_l) == info + + From arigo at codespeak.net Fri Oct 14 18:19:31 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 18:19:31 +0200 (CEST) Subject: [pypy-svn] r18571 - in pypy/dist/pypy: annotation translator Message-ID: <20051014161931.5F0B427B5A@code1.codespeak.net> Author: arigo Date: Fri Oct 14 18:19:30 2005 New Revision: 18571 Removed: pypy/dist/pypy/annotation/ pypy/dist/pypy/translator/translator.py Log: removed, will be copied from the hl-backend branch From arigo at codespeak.net Fri Oct 14 18:20:37 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 18:20:37 +0200 (CEST) Subject: [pypy-svn] r18572 - in pypy/dist/pypy: annotation translator Message-ID: <20051014162037.6A8DC27B5A@code1.codespeak.net> Author: arigo Date: Fri Oct 14 18:20:36 2005 New Revision: 18572 Added: pypy/dist/pypy/annotation/ - copied from r18571, pypy/branch/hl-backend/pypy/annotation/ pypy/dist/pypy/translator/translator.py - copied unchanged from r18571, pypy/branch/hl-backend/pypy/translator/translator.py Log: copied from the hl-backend branch. From afa at codespeak.net Fri Oct 14 18:25:23 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 14 Oct 2005 18:25:23 +0200 (CEST) Subject: [pypy-svn] r18573 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051014162523.D5A7B27B74@code1.codespeak.net> Author: afa Date: Fri Oct 14 18:25:21 2005 New Revision: 18573 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: valentino, afa: socket module: all functions are implemented still missing is the SocketType... Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Fri Oct 14 18:25:21 2005 @@ -171,9 +171,7 @@ return space.wrap(socket.inet_ntop(af, packed)) inet_ntop.unwrap_spec = [ObjSpace, int, str] -def getaddrinfo(space, w_host, w_port, w_family=NoneNotWrapped, - w_socktype=None, w_proto=None, - w_flags=None): +def getaddrinfo(space, w_host, w_port, family=0, socktype=0, proto=0, flags=0): """getaddrinfo(host, port [, family, socktype, proto, flags]) -> list of (family, socktype, proto, canonname, sockaddr) @@ -188,18 +186,35 @@ else: port = space.str_w(w_port) - if w_family is None: - return space.wrap(socket.getaddrinfo(host, port)) - else: - family = space.int_w(w_family) - socktype = space.int_w(w_socktype) - proto = space.int_w(w_proto) - flags = space.int_w(w_flags) - return space.wrap(socket.getaddrinfo(host, port, family, socktype, proto, flags)) -getaddrinfo.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root, W_Root, W_Root, W_Root] - + return space.wrap(socket.getaddrinfo(host, port, family, socktype, proto, flags)) +getaddrinfo.unwrap_spec = [ObjSpace, W_Root, W_Root, int, int, int, int] + +def getnameinfo(space, w_sockaddr, flags): + """getnameinfo(sockaddr, flags) --> (host, port) + + Get host and port for a sockaddr.""" + sockaddr = space.unwrap(w_sockaddr) + return space.wrap(socket.getnameinfo(sockaddr, flags)) +getnameinfo.unwrap_spec = [ObjSpace, W_Root, int] + +def getdefaulttimeout(space): + """getdefaulttimeout() -> timeout + + Returns the default timeout in floating seconds for new socket objects. + A value of None indicates that new socket objects have no timeout. + When the socket module is first imported, the default is None. + """ + return space.wrap(socket.getdefaulttimeout()) +getdefaulttimeout.unwrap_spec = [ObjSpace] +def setdefaulttimeout(space, w_timeout): + """setdefaulttimeout(timeout) + Set the default timeout in floating seconds for new socket objects. + A value of None indicates that new socket objects have no timeout. + When the socket module is first imported, the default is None. + """ + timeout = space.unwrap(w_timeout) + return space.wrap(socket.setdefaulttimeout(timeout)) +setdefaulttimeout.unwrap_spec = [ObjSpace, W_Root] -# getaddrinfo getnameinfo -# getdefaulttimeout setdefaulttimeout Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Fri Oct 14 18:25:21 2005 @@ -148,17 +148,32 @@ w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info - w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port), space.wrap(0)], - """(_socket, host, port, family): - try: - return _socket.getaddrinfo(host, port, family) - except TypeError: # arguments are missing - return [1] - """) - assert space.unwrap(w_l) == [1] py.test.skip("Too long...") w_l = space.appexec([w_socket, space.wrap(unicode(host)), space.wrap(port)], "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info +def test_getnameinfo(): + host = "localhost" + port = 25 + info = socket.getnameinfo((host, port), 0) + w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], + "(_socket, host, port): return _socket.getnameinfo((host, port), 0)") + assert space.unwrap(w_l) == info + +def test_timeout(): + space.appexec([w_socket, space.wrap(25.4)], + "(_socket, timeout): _socket.setdefaulttimeout(timeout)") + w_t = space.appexec([w_socket], + "(_socket): return _socket.getdefaulttimeout()") + assert space.unwrap(w_t) == 25.4 + + space.appexec([w_socket, space.w_None], + "(_socket, timeout): _socket.setdefaulttimeout(timeout)") + w_t = space.appexec([w_socket], + "(_socket): return _socket.getdefaulttimeout()") + assert space.unwrap(w_t) is None + + + From arigo at codespeak.net Fri Oct 14 18:33:01 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 18:33:01 +0200 (CEST) Subject: [pypy-svn] r18575 - pypy/dist/pypy/translator/squeak Message-ID: <20051014163301.6B92F27B60@code1.codespeak.net> Author: arigo Date: Fri Oct 14 18:33:00 2005 New Revision: 18575 Added: pypy/dist/pypy/translator/squeak/ - copied from r18574, pypy/branch/hl-backend/pypy/translator/squeak/ Log: forgot to copy the squeak back-end from the hl-backend branch. oups oups oups. From arigo at codespeak.net Fri Oct 14 18:37:32 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 18:37:32 +0200 (CEST) Subject: [pypy-svn] r18576 - pypy/dist/pypy/rpython Message-ID: <20051014163732.7D47027B62@code1.codespeak.net> Author: arigo Date: Fri Oct 14 18:37:31 2005 New Revision: 18576 Modified: pypy/dist/pypy/rpython/typesystem.py Log: Minor detail. Modified: pypy/dist/pypy/rpython/typesystem.py ============================================================================== --- pypy/dist/pypy/rpython/typesystem.py (original) +++ pypy/dist/pypy/rpython/typesystem.py Fri Oct 14 18:37:31 2005 @@ -53,6 +53,8 @@ self.BUILTIN_TYPER = rbuiltin.BUILTIN_TYPER return self.BUILTIN_TYPER + else: + raise AttributeError(name) def deref(self, obj): assert isinstance(lltype.typeOf(obj), lltype.Ptr) From arigo at codespeak.net Fri Oct 14 18:38:20 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 18:38:20 +0200 (CEST) Subject: [pypy-svn] r18577 - pypy/branch/hl-backend Message-ID: <20051014163820.F2CA027B6A@code1.codespeak.net> Author: arigo Date: Fri Oct 14 18:38:20 2005 New Revision: 18577 Removed: pypy/branch/hl-backend/ Log: Removed the branch, merge completed. From afa at codespeak.net Fri Oct 14 18:40:34 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 14 Oct 2005 18:40:34 +0200 (CEST) Subject: [pypy-svn] r18578 - in pypy/dist/pypy: objspace/flow rpython rpython/test translator/c/test Message-ID: <20051014164034.AD0B127B75@code1.codespeak.net> Author: afa Date: Fri Oct 14 18:40:31 2005 New Revision: 18578 Modified: pypy/dist/pypy/objspace/flow/objspace.py pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/rpython/test/test_rbuiltin.py pypy/dist/pypy/translator/c/test/test_annotated.py Log: valentino, afa: chr(256) should raise an error. pypy silently wrapped around values. Modified: pypy/dist/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/objspace.py (original) +++ pypy/dist/pypy/objspace/flow/objspace.py Fri Oct 14 18:40:31 2005 @@ -436,6 +436,7 @@ implicit_exceptions = { int: [ValueError], # built-ins that can always raise exceptions + chr: [ValueError], } def _add_exceptions(names, exc): Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Fri Oct 14 18:40:31 2005 @@ -213,6 +213,9 @@ def rtype_chr(_, hop): vlist = hop.inputargs(Signed) + if hop.has_implicit_exception(ValueError): + hop.exception_is_here() + hop.gendirectcall(ll_check_chr, vlist[0]) return hop.genop('cast_int_to_char', vlist, resulttype=Char) def rtype_unichr(_, hop): @@ -405,6 +408,12 @@ def ll_hash_int(n): return n +def ll_check_chr(n): + if 0 <= n <= 255: + return + else: + raise ValueError + # # _________________________ Conversions _________________________ 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 Fri Oct 14 18:40:31 2005 @@ -276,3 +276,16 @@ return x res = interpret(f, [0]) assert res == 3 + +def test_chr(): + def f(x=int): + try: + return chr(x) + except ValueError: + return '?' + res = interpret(f, [65]) + assert res == 'A' + res = interpret(f, [256]) + assert res == '?' + res = interpret(f, [-1]) + assert res == '?' Modified: pypy/dist/pypy/translator/c/test/test_annotated.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_annotated.py (original) +++ pypy/dist/pypy/translator/c/test/test_annotated.py Fri Oct 14 18:40:31 2005 @@ -177,3 +177,14 @@ assert fn(2) == 0 py.test.raises(MemoryError, fn, sys.maxint//2+1) py.test.raises(MemoryError, fn, sys.maxint) + + def test_chr(self): + def f(x=int): + try: + return 'Yes ' + chr(x) + except ValueError: + return 'No' + fn = self.getcompiled(f) + assert fn(65) == 'Yes A' + assert fn(256) == 'No' + assert fn(-1) == 'No' From tismer at codespeak.net Fri Oct 14 18:40:57 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Fri, 14 Oct 2005 18:40:57 +0200 (CEST) Subject: [pypy-svn] r18579 - in pypy/dist/pypy/translator: c goal Message-ID: <20051014164057.9AF0227B7C@code1.codespeak.net> Author: tismer Date: Fri Oct 14 18:40:55 2005 New Revision: 18579 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/goal/driver.py pypy/dist/pypy/translator/goal/translate_pypy.py Log: splitted translate_pypy's source step into two: There is now an extra database step in driver.py. This was done in order to take a fork/snapshot right before the source is generated. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Fri Oct 14 18:40:55 2005 @@ -25,21 +25,33 @@ libraries = [] self.libraries = libraries - def generate_source(self): - assert self.c_source_filename is None + def build_database(self): translator = self.translator - pf = self.getentrypointptr() db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicy=self.gcpolicy) if self.stackless: from pypy.translator.c.stackless import StacklessData db.stacklessdata = StacklessData() - # we need a concrete gcpolicy to do this + # we need a concrete gcpolicy to do this self.libraries += db.gcpolicy.gc_libraries() + # XXX the following has the side effect to generate + # some needed things. Find out why. + pf = self.getentrypointptr() pfname = db.get(pf) + # XXX db.complete() + return db + + def generate_source(self, db=None): + assert self.c_source_filename is None + translator = self.translator + + if db is None: + db = self.build_database() + pf = self.getentrypointptr() + pfname = db.get(pf) modulename = uniquemodulename('testing') targetdir = udir.ensure(modulename, dir=1) Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Fri Oct 14 18:40:55 2005 @@ -174,7 +174,7 @@ task_backendopt = taskdef(task_backendopt, ['rtype'], "Back-end optimisations") - def task_source_c(self): # xxx messy + def task_database_c(self): translator = self.translator opt = self.options if translator.annotator is not None: @@ -191,13 +191,23 @@ cbuilder = translator.cbuilder(standalone=standalone, gcpolicy=gcpolicy) cbuilder.stackless = opt.stackless - c_source_filename = cbuilder.generate_source() - self.log.info("written: %s" % (c_source_filename,)) + database = cbuilder.build_database() + self.log.info("database for generating C source was created") self.cbuilder = cbuilder + self.database = database # - task_source_c = taskdef(task_source_c, + task_database_c = taskdef(task_database_c, ['?backendopt', '?rtype', '?annotate'], - "Generating c source") + "Creating database for generating c source") + + def task_source_c(self): # xxx messy + translator = self.translator + cbuilder = self.cbuilder + database = self.database + c_source_filename = cbuilder.generate_source(database) + self.log.info("written: %s" % (c_source_filename,)) + # + task_source_c = taskdef(task_source_c, ['database_c'], "Generating c source") def task_compile_c(self): # xxx messy cbuilder = self.cbuilder 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 Oct 14 18:40:55 2005 @@ -75,7 +75,7 @@ (see pypy/translator/tool/pygame/graphclient.py)""", int)], '5_fork_before': [OPT(('--fork-before',), """(UNIX) Create restartable checkpoint before step""", - ['annotate', 'rtype', 'backendopt', 'source'])], + ['annotate', 'rtype', 'backendopt', 'database', 'source'])], '6_llinterpret': [OPT(('--llinterpret',), "Interpret the rtyped flow graphs", GOAL)], }, From hpk at codespeak.net Fri Oct 14 18:53:53 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 14 Oct 2005 18:53:53 +0200 (CEST) Subject: [pypy-svn] r18580 - pypy/extradoc/talk Message-ID: <20051014165353.69E6627B5A@code1.codespeak.net> Author: hpk Date: Fri Oct 14 18:53:49 2005 New Revision: 18580 Added: pypy/extradoc/talk/sprint-basic-intro.sxi (contents, props changed) Log: an old architecture overview i did and reused when introducing at the paris sprint. Needs some updates, though ... Added: pypy/extradoc/talk/sprint-basic-intro.sxi ============================================================================== Binary file. No diff available. From arigo at codespeak.net Fri Oct 14 18:59:37 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 18:59:37 +0200 (CEST) Subject: [pypy-svn] r18582 - pypy/dist/pypy/interpreter Message-ID: <20051014165937.7DBF027B57@code1.codespeak.net> Author: arigo Date: Fri Oct 14 18:59:36 2005 New Revision: 18582 Modified: pypy/dist/pypy/interpreter/argument.py Log: avoid using a slice 'lst[n:]' in RPython if n>len(lst). Modified: pypy/dist/pypy/interpreter/argument.py ============================================================================== --- pypy/dist/pypy/interpreter/argument.py (original) +++ pypy/dist/pypy/interpreter/argument.py Fri Oct 14 18:59:36 2005 @@ -207,7 +207,11 @@ # collect extra positional arguments into the *vararg if varargname is not None: if self.w_stararg is None: # common case - scope_w.append(self.space.newtuple(args_w[co_argcount:])) + if len(args_w) > co_argcount: # check required by rpython + starargs_w = args_w[co_argcount:] + else: + starargs_w = [] + scope_w.append(self.space.newtuple(starargs_w)) else: # shortcut for the non-unpack() case above scope_w.append(self.w_stararg) elif len(args_w) > co_argcount: From ac at codespeak.net Fri Oct 14 19:23:50 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Fri, 14 Oct 2005 19:23:50 +0200 (CEST) Subject: [pypy-svn] r18585 - in pypy/dist/pypy/interpreter: astcompiler pyparser pyparser/test Message-ID: <20051014172350.3761027B68@code1.codespeak.net> Author: ac Date: Fri Oct 14 19:23:49 2005 New Revision: 18585 Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Log: (arre, adim) Generate proper lineno for lists of constants. Have tuples of constants only generate a LOAD_CONST of the tuple. Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Fri Oct 14 19:23:49 2005 @@ -316,6 +316,7 @@ self.scope = node.scope self.emitop_int('SET_LINENO', 0) if not space.is_w(node.doc, space.w_None): + self.set_lineno(node) self.emitop_obj('LOAD_CONST', node.doc) self.storeName('__doc__', node.lineno) node.node.accept( self ) @@ -818,6 +819,9 @@ self.emit('POP_TOP') def visitConst(self, node): + space = self.space + if space.is_true(space.isinstance(node.value, space.w_tuple)): + self.set_lineno(node) self.emitop_obj('LOAD_CONST', node.value) def visitKeyword(self, node): Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Fri Oct 14 19:23:49 2005 @@ -538,6 +538,7 @@ builder.push(ast.List([], top.lineno)) else: list_node = atoms[1] + list_node.lineno = top.lineno builder.push(list_node) elif top.name == tok.LBRACE: items = [] @@ -888,7 +889,13 @@ genexpr_for[0].is_outmost = True builder.push(ast.GenExpr(ast.GenExprInner(expr, genexpr_for, lineno), lineno)) return - builder.push(ast.Tuple(items, lineno)) + isConst = True + for item in items: + isConst &= isinstance(item,ast.Const) + if isConst: + builder.push(ast.Const(builder.space.newtuple([i.value for i in items]), lineno)) + else: + builder.push(ast.Tuple(items, lineno)) return def build_lambdef(builder, nb): @@ -926,8 +933,7 @@ num_slicevals = 2 for val in atom.value[:num_slicevals]: if val is None: - slicevals.append(ast.Const(builder.wrap_none(), - atom.lineno)) + slicevals.append(ast.Const(builder.wrap_none(), atom.lineno)) else: slicevals.append(val) subs.append(ast.Sliceobj(slicevals, atom.lineno)) @@ -1190,9 +1196,14 @@ builder.push(atoms[0]) else: names = [] + isConst = True for index in range(0, len(atoms), 2): names.append(atoms[index]) - builder.push(ast.Tuple(names, atoms[0].lineno)) + isConst &= isinstance(atoms[index],ast.Const) + if isConst: + builder.push(ast.Const(builder.space.newtuple([n.value for n in names]), atoms[0].lineno)) + else: + builder.push(ast.Tuple(names, atoms[0].lineno)) def build_while_stmt(builder, nb): 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 Oct 14 19:23:49 2005 @@ -683,7 +683,7 @@ 'snippet_whitespaces.py', 'snippet_samples.py', 'snippet_decorators.py', - 'snippet_listlinenos.py', + # 'snippet_listlinenos.py', 'snippet_whilelineno.py', ] From cfbolz at codespeak.net Fri Oct 14 19:26:04 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 14 Oct 2005 19:26:04 +0200 (CEST) Subject: [pypy-svn] r18587 - pypy/extradoc/talk Message-ID: <20051014172604.CC8AE27B6D@code1.codespeak.net> Author: cfbolz Date: Fri Oct 14 19:26:03 2005 New Revision: 18587 Added: pypy/extradoc/talk/gc_slides.txt pypy/extradoc/talk/liveness.dot Log: the slides of the GC introduction given at the paris sprint Added: pypy/extradoc/talk/gc_slides.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/gc_slides.txt Fri Oct 14 19:26:03 2005 @@ -0,0 +1,169 @@ +============================================= +Garbage Collection in PyPy -- Summer of Code +============================================= + +Thanks to Google for sponsoring this work! + +Goals +----- + + * following PyPy's main scheme: implementing Garbage Collection in Python! + * flexibility, simplicity + * bla + * bla + * bla + + +========= +Addresses +========= + + * Addresses (pypy.rpython.memory.lladdress.address) provide a general method + to access blobs of memory + + * Example usage:: + + addr = raw_malloc(16) + addr.signed[0] = 1 + assert addr.signed[0] == 1 + addr.signed[1] = 42 + assert (addr + 4).signed[0] == 42 + raw_free(addr) + + * running on Python, they are simulated with extra checks:: + + addr.signed[0] --> Crash + +=========================== +Explicitely managed classes +=========================== + + * To have a higher level way to explicitely manage memory, you can declare a + class to be explicitely freed:: + + class A(object): + _malloc_flavor_ = 'raw' + def __init__(self, b): + self.b = b + a = A(1) + assert a.b == 1 + free_non_gc_object(a) + + * running on Python there free_non_gc_object does things to remind you of the + fact that the instance was freed:: + + a.b --> Crash + + +================== +Garbage Collection +================== + + * Garbage Collection is a way to automatically free objects that can be no + longer accessed by the user program (mutator) + * This is generally done by starting from the *roots*: + * the are the objects the program can access at the moment + * basically all the pointers in the stack plus Constants + * From the roots on the GC recursively follows all the embedded pointers + * every object that can be reached by this method is life + * every object that can not be reached is considered garbage and can be + deleted (after such annoying things like finalization) + +======= +Example +======= + +.. raw:: html + +
+
+
+ + +.. image:: liveness.png + +.. raw:: html + +
+
+
+ + + + +======================== +Memory Layout of the GCs +======================== + + * The GC needs information about the objects it collects to find the + contained pointers + * This information is stored in front of the object:: + + +---<- program sees only this + | + +---------+---------+----------------------------+ + | gc info | type id | object data | + | signed | signed | whatever ... | + +---------+---------+----------------------------+ + + * the GC decides what it stores there -- even nothing + * most GCs need the typeid, it provides access to the information a GC needs + to know about a type + + +==================== +Type query functions +==================== + + * ``is_varsize(typeid) --> bool`` + * ``offsets_to_gc_pointers(typeid)`` --> list of offsets + * ``fixed_size(typeid)`` --> size + * ``varsize_item_sizes(typeid)`` --> size + * ``varsize_offset_to_variable_part(typeid)`` --> offset + * ``varsize_offset_to_length(typeid)`` --> offset + * ``varsize_offsets_to_gcpointers_in_var_part(typeid)`` --> list of offsets + * the GC uses these functions to get details about object layout + * the typeids are retrieved from the memory in front of the object + +.. raw:: html + +
+
+
+
+ + +========== +GC methods +========== + + * ``malloc(self, typeid, length=0)`` --> address + * ``collect(self) --> None`` + * ``size_gc_header(self, typeid)`` --> size + * ``init_gc_object(self, addr, typeid) --> None`` + * ``init_gc_object_immortal(self, addr, typeid) --> None`` + * ``write_barrier(self, addr, addr_to, addr_struct) --> None`` + +.. raw:: html + +
+
+
+
+
+
+ + +============================== +Tying the GC into the LLInterp +============================== + + * for now using a GC works only using the LLInterpreter, since you can't + reliably find roots in C + * some operations are implemented by calling methods of the GC: + * ``setfield, setarrayitem --> write_barrier`` + * ``malloc, malloc_varsize --> malloc`` + * there has to be a way to call ``collect`` from user level, some fishing + needed + * ``init_gc_object_immortal`` is called by the code that converts + the constants in a graph to a format the GC can use Added: pypy/extradoc/talk/liveness.dot ============================================================================== --- (empty file) +++ pypy/extradoc/talk/liveness.dot Fri Oct 14 19:26:03 2005 @@ -0,0 +1,28 @@ +digraph g { + node [shape=Mrecord, height=0.1]; + roots [label="root1|root2", color=green]; + object0 [label="||2.71|

"]; + object1 [label="||3.14|

"]; + object2 [label="||1.41|

", color=darksalmon]; + object3 [label="||1.65|

", color=darksalmon]; + object4 [label="||0.71|

", color=darksalmon]; + string1 [label="-152653889|'string1'"]; + subgraph bottom { + rank=same; + class0 [label="||'Klass'"]; + string2 [label="-2129553658|'garbage'", color=darksalmon]; + } + + roots:r0 -> string1:start [style=bold]; + roots:r1 -> object0:start [style=bold]; + object0:cls -> class0:start [style=bold]; + object0:p -> object1:start [style=bold]; + object1:cls -> class0:start [style=bold]; + object2:cls -> class0:start; + object2:p -> object1:start; + + object3:p -> object4:start; + object3:cls -> class0:start; + object4:p -> object3:start; + object4:cls -> class0:start; +} From ale at codespeak.net Fri Oct 14 19:35:25 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Fri, 14 Oct 2005 19:35:25 +0200 (CEST) Subject: [pypy-svn] r18588 - pypy/dist/lib-python Message-ID: <20051014173525.8727527B60@code1.codespeak.net> Author: ale Date: Fri Oct 14 19:35:24 2005 New Revision: 18588 Modified: pypy/dist/lib-python/conftest.py Log: Added option to run the compliancy tests with a compiled pypy-c living in pypy/bin/ TODO : be better at reporting segfaults better reporting of version of compiled pypy Preliminary results: Some tests still take a lot of time (test_long, test_marshal ....) A lot of tests fails because of some mismatch between IOError (expected by test_support) and OSError (raised by lib/_file) Modified: pypy/dist/lib-python/conftest.py ============================================================================== --- pypy/dist/lib-python/conftest.py (original) +++ pypy/dist/lib-python/conftest.py Fri Oct 14 19:35:24 2005 @@ -35,6 +35,9 @@ Option = py.test.Config.Option option = py.test.Config.addoptions("compliance testing options", + Option('-C', '--compiled', action="store_true", + default=False, dest="use_compiled", + help="use a compiled version of pypy, expected in pypy/bin/pypy-c"), Option('-E', '--extracttests', action="store_true", default=False, dest="extracttests", help="try to extract single tests and run them via py.test/PyPy"), @@ -889,7 +892,14 @@ regrrun_verbosity = regrtest.getoutputpath() and '0' or '1' TIMEOUT = gettimeout() - cmd = "%s %s %d %s %s %s %s %s" %( + if option.use_compiled: + python = pypydir.join('bin', 'pypy-c') + cmd = "%s %s %s %s" %( + python, + regrrun, regrrun_verbosity, fspath.purebasename) + print cmd + else: + cmd = "%s %s %d %s %s %s %s %s" %( python, alarm_script, TIMEOUT, pypy_script, sopt, regrrun, regrrun_verbosity, fspath.purebasename) @@ -952,9 +962,13 @@ cmd = self.getinvocation(regrtest) result = Result() fspath = regrtest.getfspath() - result['fspath'] = str(fspath) + result['fspath'] = str(fspath) + if option.use_compiled: + #Please fix this, breaks the report table + result['pypy-revision'] = '%s compiled' % getrev(pypydir) + else: + result['pypy-revision'] = getrev(pypydir) result['options'] = regrtest.getoptions() - result['pypy-revision'] = getrev(pypydir) result['timeout'] = gettimeout() result['startdate'] = time.ctime() starttime = time.time() @@ -980,6 +994,9 @@ res, out, err = callcapture(reportdiff, expected, test_stdout) outcome = 'ERROUT' result.addnamedtext('reportdiff', out) + else: + if 'FAIL' in test_stdout or 'ERROR' in test_stderr: + outcome = 'FAIL' elif timedout: outcome = "T/O" else: From boria at codespeak.net Fri Oct 14 19:46:06 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Fri, 14 Oct 2005 19:46:06 +0200 (CEST) Subject: [pypy-svn] r18589 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem/test Message-ID: <20051014174606.1885427B60@code1.codespeak.net> Author: boria Date: Fri Oct 14 19:45:28 2005 New Revision: 18589 Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/rpbc.py pypy/dist/pypy/rpython/typesystem.py Log: (mwh, boria) * Fix indentation in rtype_is_None(). * Add a check_null() to typesystem.py. * Move MultiplePBCRepr and FunctionsPBCRepr back to rpython/rpbc.py. * One more test now passes in ootypesystem/test/test_ooclean.py. Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Fri Oct 14 19:45:28 2005 @@ -10,33 +10,21 @@ from pypy.rpython import robject from pypy.rpython import rtuple from pypy.rpython.rpbc import SingleFrozenPBCRepr, getsignature, samesig,\ - commonbase, allattributenames, get_access_set + commonbase, allattributenames, get_access_set,\ + MultiplePBCRepr, FunctionsPBCRepr from pypy.rpython.lltypesystem import rclass from pypy.tool.sourcetools import has_varargs from pypy.rpython import callparse def rtype_is_None(robj1, rnone2, hop, pos=0): - if not isinstance(robj1.lowleveltype, Ptr): - raise TyperError('is None of instance of the non-pointer: %r' % (robj1)) - v1 = hop.inputarg(robj1, pos) - return hop.genop('ptr_iszero', [v1], resulttype=Bool) + if not isinstance(robj1.lowleveltype, Ptr): + raise TyperError('is None of instance of the non-pointer: %r' % (robj1)) + v1 = hop.inputarg(robj1, pos) + return hop.genop('ptr_iszero', [v1], resulttype=Bool) # ____________________________________________________________ -class MultiplePBCRepr(Repr): - """Base class for PBCReprs of multiple PBCs that can include None - (represented as a NULL pointer).""" - def rtype_is_true(self, hop): - if hop.s_result.is_constant(): - assert hop.s_result.const is True # custom __nonzero__ on PBCs? - return hop.inputconst(Bool, hop.s_result.const) - else: - # None is a nullptr, which is false; everything else is true. - vlist = hop.inputargs(self) - return hop.genop('ptr_nonzero', vlist, resulttype=Bool) - - class MultipleFrozenPBCRepr(MultiplePBCRepr): """Representation selected for multiple non-callable pre-built constants.""" def __init__(self, rtyper, access_set): @@ -185,116 +173,6 @@ # ____________________________________________________________ - -class FunctionsPBCRepr(MultiplePBCRepr): - """Representation selected for a PBC of function(s).""" - - def __init__(self, rtyper, s_pbc): - self.rtyper = rtyper - self.s_pbc = s_pbc - self._function_signatures = None - if len(s_pbc.prebuiltinstances) == 1: - # a single function - self.lowleveltype = Void - else: - signatures = self.function_signatures().values() - sig0 = signatures[0] - for sig1 in signatures[1:]: - assert typeOf(sig0[0]) == typeOf(sig1[0]) # XXX not implemented - assert sig0[1:] == sig1[1:] # XXX not implemented - self.lowleveltype = typeOf(sig0[0]) - - def get_s_callable(self): - return self.s_pbc - - def get_r_implfunc(self): - return self, 0 - - def get_signature(self): - return self.function_signatures().itervalues().next() - - def get_args_ret_s(self): - f, _, _ = self.get_signature() - graph = self.rtyper.type_system_deref(f).graph - rtyper = self.rtyper - return [rtyper.binding(arg) for arg in graph.getargs()], rtyper.binding(graph.getreturnvar()) - - def function_signatures(self): - if self._function_signatures is None: - self._function_signatures = {} - for func in self.s_pbc.prebuiltinstances: - if func is not None: - self._function_signatures[func] = getsignature(self.rtyper, - func) - assert self._function_signatures - return self._function_signatures - - def convert_const(self, value): - if value is None: - return nullptr(self.lowleveltype.TO) - if isinstance(value, types.MethodType) and value.im_self is None: - value = value.im_func # unbound method -> bare function - if value not in self.function_signatures(): - raise TyperError("%r not in %r" % (value, - self.s_pbc.prebuiltinstances)) - f, rinputs, rresult = self.function_signatures()[value] - return f - - def rtype_simple_call(self, hop): - f, rinputs, rresult = self.function_signatures().itervalues().next() - - if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): - # should not have an argument count mismatch - assert len(rinputs) == hop.nb_args-1, "normalization bug" - vlist = hop.inputargs(self, *rinputs) - else: - # if not normalized, should be a call to a known function - # or to functions all with same signature - funcs = self.function_signatures().keys() - assert samesig(funcs), "normalization bug" - func = funcs[0] - vlist = [hop.inputarg(self, arg=0)] - vlist += callparse.callparse('simple_call', func, rinputs, hop) - - return self.call(hop, f, vlist, rresult) - - def call(self, hop, f, vlist, rresult): - if self.lowleveltype is 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) - - def rtype_call_args(self, hop): - f, rinputs, rresult = self.function_signatures().itervalues().next() - # the function arguments may have been normalized by normalizecalls() - # already - if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): - vlist = hop.inputargs(self, Void, *rinputs) - vlist = vlist[:1] + vlist[2:] - else: - # if not normalized, should be a call to a known function - # or to functions all with same signature - funcs = self.function_signatures().keys() - assert samesig(funcs), "normalization bug" - func = funcs[0] - vlist = [hop.inputarg(self, arg=0)] - vlist += callparse.callparse('call_args', func, rinputs, hop) - - return self.call(hop, f, vlist, rresult) - -class __extend__(pairtype(FunctionsPBCRepr, FunctionsPBCRepr)): - def convert_from_to((r_fpbc1, r_fpbc2), v, llops): - # this check makes sense because both source and dest repr are FunctionsPBCRepr - if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: - return v - if r_fpbc1.lowleveltype is Void: - return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) - return NotImplemented - -# ____________________________________________________________ - class MethodsPBCRepr(Repr): """Representation selected for a PBC of the form {func: classdef...}. It assumes that all the methods come from the same name in a base Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Fri Oct 14 19:45:28 2005 @@ -26,7 +26,7 @@ return a + b specialize(f, [int, int]) -def inprogress_test_simple_call(): +def test_simple_call(): def f(a, b): return a + b Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Fri Oct 14 19:45:28 2005 @@ -60,7 +60,7 @@ # other kind of callable if isinstance(x, types.FunctionType): # function - choice = rtyper.type_system.rpbc.FunctionsPBCRepr + choice = FunctionsPBCRepr elif isinstance(x, types.MethodType): # prebuilt bound method choice = rtyper.type_system.rpbc.MethodOfFrozenPBCRepr @@ -100,6 +100,123 @@ # ____________________________________________________________ +class MultiplePBCRepr(Repr): + """Base class for PBCReprs of multiple PBCs that can include None + (represented as a NULL pointer).""" + def rtype_is_true(self, hop): + if hop.s_result.is_constant(): + assert hop.s_result.const is True # custom __nonzero__ on PBCs? + return hop.inputconst(Bool, hop.s_result.const) + else: + return hop.rtyper.type_system.check_null(self, hop) + +class FunctionsPBCRepr(MultiplePBCRepr): + """Representation selected for a PBC of function(s).""" + + def __init__(self, rtyper, s_pbc): + self.rtyper = rtyper + self.s_pbc = s_pbc + self._function_signatures = None + if len(s_pbc.prebuiltinstances) == 1: + # a single function + self.lowleveltype = Void + else: + signatures = self.function_signatures().values() + sig0 = signatures[0] + for sig1 in signatures[1:]: + assert typeOf(sig0[0]) == typeOf(sig1[0]) # XXX not implemented + assert sig0[1:] == sig1[1:] # XXX not implemented + self.lowleveltype = typeOf(sig0[0]) + + def get_s_callable(self): + return self.s_pbc + + def get_r_implfunc(self): + return self, 0 + + def get_signature(self): + return self.function_signatures().itervalues().next() + + def get_args_ret_s(self): + f, _, _ = self.get_signature() + graph = self.rtyper.type_system_deref(f).graph + rtyper = self.rtyper + return [rtyper.binding(arg) for arg in graph.getargs()], rtyper.binding(graph.getreturnvar()) + + def function_signatures(self): + if self._function_signatures is None: + self._function_signatures = {} + for func in self.s_pbc.prebuiltinstances: + if func is not None: + self._function_signatures[func] = getsignature(self.rtyper, + func) + assert self._function_signatures + return self._function_signatures + + def convert_const(self, value): + if value is None: + return nullptr(self.lowleveltype.TO) + if isinstance(value, types.MethodType) and value.im_self is None: + value = value.im_func # unbound method -> bare function + if value not in self.function_signatures(): + raise TyperError("%r not in %r" % (value, + self.s_pbc.prebuiltinstances)) + f, rinputs, rresult = self.function_signatures()[value] + return f + + def rtype_simple_call(self, hop): + f, rinputs, rresult = self.function_signatures().itervalues().next() + + if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): + # should not have an argument count mismatch + assert len(rinputs) == hop.nb_args-1, "normalization bug" + vlist = hop.inputargs(self, *rinputs) + else: + # if not normalized, should be a call to a known function + # or to functions all with same signature + funcs = self.function_signatures().keys() + assert samesig(funcs), "normalization bug" + func = funcs[0] + vlist = [hop.inputarg(self, arg=0)] + vlist += callparse.callparse('simple_call', func, rinputs, hop) + + return self.call(hop, f, vlist, rresult) + + def call(self, hop, f, vlist, rresult): + if self.lowleveltype is 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) + + def rtype_call_args(self, hop): + f, rinputs, rresult = self.function_signatures().itervalues().next() + # the function arguments may have been normalized by normalizecalls() + # already + if getattr(self.rtyper.type_system_deref(f).graph, 'normalized_for_calls', False): + vlist = hop.inputargs(self, Void, *rinputs) + vlist = vlist[:1] + vlist[2:] + else: + # if not normalized, should be a call to a known function + # or to functions all with same signature + funcs = self.function_signatures().keys() + assert samesig(funcs), "normalization bug" + func = funcs[0] + vlist = [hop.inputarg(self, arg=0)] + vlist += callparse.callparse('call_args', func, rinputs, hop) + + return self.call(hop, f, vlist, rresult) + +class __extend__(pairtype(FunctionsPBCRepr, FunctionsPBCRepr)): + def convert_from_to((r_fpbc1, r_fpbc2), v, llops): + # this check makes sense because both source and dest repr are FunctionsPBCRepr + if r_fpbc1.lowleveltype == r_fpbc2.lowleveltype: + return v + if r_fpbc1.lowleveltype is Void: + return inputconst(r_fpbc2, r_fpbc1.s_pbc.const) + return NotImplemented + def getPyObjRepr(rtyper, s_pbc): return robject.pyobj_repr Modified: pypy/dist/pypy/rpython/typesystem.py ============================================================================== --- pypy/dist/pypy/rpython/typesystem.py (original) +++ pypy/dist/pypy/rpython/typesystem.py Fri Oct 14 19:45:28 2005 @@ -13,6 +13,11 @@ """Dereference `obj' to concrete object.""" raise NotImplementedError() + def check_null(self, repr, hop): + """Emit operations to check that `hop's argument is not a null object. +""" + raise NotImplementedError() + def getcallable(self, translator, graphfunc, getconcretetype=None): """Return callable given a Python function.""" if getconcretetype is None: @@ -60,6 +65,11 @@ assert isinstance(lltype.typeOf(obj), lltype.Ptr) return obj._obj + def check_null(self, repr, hop): + # None is a nullptr, which is false; everything else is true. + vlist = hop.inputargs(repr) + return hop.genop('ptr_nonzero', vlist, resulttype=lltype.Bool) + def getconcretetype(self, v): return getattr(v, 'concretetype', lltype.Ptr(lltype.PyObject)) From afa at codespeak.net Fri Oct 14 19:57:59 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Fri, 14 Oct 2005 19:57:59 +0200 (CEST) Subject: [pypy-svn] r18590 - pypy/dist/pypy/module/_socket Message-ID: <20051014175759.9D6C427B56@code1.codespeak.net> Author: afa Date: Fri Oct 14 19:57:32 2005 New Revision: 18590 Modified: pypy/dist/pypy/module/_socket/interp_socket.py Log: valentino, afa: exception handling in socket module still a lot of work to do, to re-implement logic Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Fri Oct 14 19:57:32 2005 @@ -1,15 +1,94 @@ -import socket +import socket, errno, sys from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import W_Root from pypy.interpreter.gateway import ObjSpace, NoneNotWrapped +#w_socketerror = ??? + +if sys.platform == 'win32': + WIN32_ERROR_MESSAGES = { + errno.WSAEINTR: "Interrupted system call", + errno.WSAEBADF: "Bad file descriptor", + errno.WSAEACCES: "Permission denied", + errno.WSAEFAULT: "Bad address", + errno.WSAEINVAL: "Invalid argument", + errno.WSAEMFILE: "Too many open files", + errno.WSAEWOULDBLOCK: + "The socket operation could not complete without blocking", + errno.WSAEINPROGRESS: "Operation now in progress", + errno.WSAEALREADY: "Operation already in progress", + errno.WSAENOTSOCK: "Socket operation on non-socket", + errno.WSAEDESTADDRREQ: "Destination address required", + errno.WSAEMSGSIZE: "Message too long", + errno.WSAEPROTOTYPE: "Protocol wrong type for socket", + errno.WSAENOPROTOOPT: "Protocol not available", + errno.WSAEPROTONOSUPPORT: "Protocol not supported", + errno.WSAESOCKTNOSUPPORT: "Socket type not supported", + errno.WSAEOPNOTSUPP: "Operation not supported", + errno.WSAEPFNOSUPPORT: "Protocol family not supported", + errno.WSAEAFNOSUPPORT: "Address family not supported", + errno.WSAEADDRINUSE: "Address already in use", + errno.WSAEADDRNOTAVAIL: "Can't assign requested address", + errno.WSAENETDOWN: "Network is down", + errno.WSAENETUNREACH: "Network is unreachable", + errno.WSAENETRESET: "Network dropped connection on reset", + errno.WSAECONNABORTED: "Software caused connection abort", + errno.WSAECONNRESET: "Connection reset by peer", + errno.WSAENOBUFS: "No buffer space available", + errno.WSAEISCONN: "Socket is already connected", + errno.WSAENOTCONN: "Socket is not connected", + errno.WSAESHUTDOWN: "Can't send after socket shutdown", + errno.WSAETOOMANYREFS: "Too many references: can't splice", + errno.WSAETIMEDOUT: "Operation timed out", + errno.WSAECONNREFUSED: "Connection refused", + errno.WSAELOOP: "Too many levels of symbolic links", + errno.WSAENAMETOOLONG: "File name too long", + errno.WSAEHOSTDOWN: "Host is down", + errno.WSAEHOSTUNREACH: "No route to host", + errno.WSAENOTEMPTY: "Directory not empty", + errno.WSAEPROCLIM: "Too many processes", + errno.WSAEUSERS: "Too many users", + errno.WSAEDQUOT: "Disc quota exceeded", + errno.WSAESTALE: "Stale NFS file handle", + errno.WSAEREMOTE: "Too many levels of remote in path", + errno.WSASYSNOTREADY: "Network subsystem is unvailable", + errno.WSAVERNOTSUPPORTED: "WinSock version is not supported", + errno.WSANOTINITIALISED: "Successful WSAStartup() not yet performed", + errno.WSAEDISCON: "Graceful shutdown in progress", + + # Resolver errors + # XXX replace by the values in winsock.h + # errno.WSAHOST_NOT_FOUND: "No such host is known", + # errno.WSATRY_AGAIN: "Host not found, or server failed", + # errno.WSANO_RECOVERY: "Unexpected server error encountered", + # errno.WSANO_DATA: "Valid name without requested data", + # errno.WSANO_ADDRESS: "No address, look for MX record", + } + + def socket_strerror(errno): + return WIN32_ERROR_MESSAGES.get(errno, "winsock error") +else: + def socket_strerror(errno): + return os.strerror(errno) + +def wrap_socketerror(space, e): + assert isinstance(e, socket.error) + errno = e.args[0] + msg = socket_strerror(errno) + w_error = space.call_function(w_socketerror, + space.wrap(errno), + space.wrap(msg)) + def gethostname(space): """gethostname() -> string Return the current host name. """ - return space.wrap(socket.gethostname()) + try: + return space.wrap(socket.gethostname()) + except socket.error, e: + return wrap_socketerror(space, e) gethostname.unwrap_spec = [ObjSpace] def gethostbyname(space, name): @@ -217,4 +296,3 @@ timeout = space.unwrap(w_timeout) return space.wrap(socket.setdefaulttimeout(timeout)) setdefaulttimeout.unwrap_spec = [ObjSpace, W_Root] - From arigo at codespeak.net Fri Oct 14 19:58:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 14 Oct 2005 19:58:02 +0200 (CEST) Subject: [pypy-svn] r18591 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20051014175802.3707927B68@code1.codespeak.net> Author: arigo Date: Fri Oct 14 19:57:23 2005 New Revision: 18591 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py Log: fix an annotation problem with the .value attribute in two places. Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Fri Oct 14 19:57:23 2005 @@ -890,10 +890,15 @@ builder.push(ast.GenExpr(ast.GenExprInner(expr, genexpr_for, lineno), lineno)) return isConst = True + values = [] for item in items: - isConst &= isinstance(item,ast.Const) + if isinstance(item, ast.Const): + values.append(item.value) + else: + isConst = False + break if isConst: - builder.push(ast.Const(builder.space.newtuple([i.value for i in items]), lineno)) + builder.push(ast.Const(builder.space.newtuple(values), lineno)) else: builder.push(ast.Tuple(items, lineno)) return @@ -1196,12 +1201,17 @@ builder.push(atoms[0]) else: names = [] + values = [] isConst = True for index in range(0, len(atoms), 2): - names.append(atoms[index]) - isConst &= isinstance(atoms[index],ast.Const) + item = atoms[index] + names.append(item) + if isinstance(item, ast.Const): + values.append(item) + else: + isConst = False if isConst: - builder.push(ast.Const(builder.space.newtuple([n.value for n in names]), atoms[0].lineno)) + builder.push(ast.Const(builder.space.newtuple(values), atoms[0].lineno)) else: builder.push(ast.Tuple(names, atoms[0].lineno)) From ericvrp at codespeak.net Fri Oct 14 22:41:23 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Fri, 14 Oct 2005 22:41:23 +0200 (CEST) Subject: [pypy-svn] r18592 - pypy/dist/pypy/translator/js Message-ID: <20051014204123.E1FFB27B4B@code1.codespeak.net> Author: ericvrp Date: Fri Oct 14 22:41:23 2005 New Revision: 18592 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/structnode.py Log: Removed more buggy code. Almost ready to wrap up pbc's and start on exception handling. [94 passed, 69 failed] Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Fri Oct 14 22:41:23 2005 @@ -105,14 +105,13 @@ def get_arrayvalue(self): items = self.value.items l = len(items) - #r = "[%s]" % ", ".join([self.db.repr_constant(v)[1] for v in items]) - r = "[%s]" % ", ".join([str(v) for v in items]) + r = "[%s]" % ", ".join([self.db.repr_constant(v)[1] for v in items]) return l, r - def get_typerepr(self): - arraylen = self.get_arrayvalue()[0] - typeval = self.db.repr_type(self.arraytype) - return "{ int, [%s x %s] }" % (arraylen, typeval) + #def get_typerepr(self): + # arraylen = self.get_arrayvalue()[0] + # typeval = self.db.repr_type(self.arraytype) + # return "{ int, [%s x %s] }" % (arraylen, typeval) def get_ref(self): return self.ref Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Fri Oct 14 22:41:23 2005 @@ -121,8 +121,8 @@ def writedecl(self, codewriter): codewriter.declare(self.ref + ' = new Object()') - def get_typerepr(self): - return self.db.repr_type(self.structtype) + #def get_typerepr(self): + # return self.db.repr_type(self.structtype) def get_childref(self, index): return self.get_ref() #XXX what to do with index? @@ -150,9 +150,9 @@ self._get_ref_cache = ref return ref - def get_pbcref(self, toptr): - """ Returns a reference as used per pbc. """ - return self.get_ref() + #def get_pbcref(self, toptr): + # """ Returns a reference as used per pbc. """ + # return self.get_ref() def constantvalue(self): """ Returns the constant representation for this node. """ @@ -208,37 +208,21 @@ def setup(self): super(StructVarsizeNode, self).setup() - def get_typerepr(self): - try: - return self._get_typerepr_cache - except: - # last type is a special case and need to be worked out recursively - types = self._get_types[:-1] - types_repr = [self.db.repr_type(T) for name, T in types] - types_repr.append(self._get_lastnode().get_typerepr()) - result = "{%s}" % ", ".join(types_repr) - self._get_typerepr_cache = result - return result + #def get_typerepr(self): + # try: + # return self._get_typerepr_cache + # except: + # # last type is a special case and need to be worked out recursively + # types = self._get_types[:-1] + # types_repr = [self.db.repr_type(T) for name, T in types] + # types_repr.append(self._get_lastnode().get_typerepr()) + # result = "{%s}" % ", ".join(types_repr) + # self._get_typerepr_cache = result + # return result def get_ref(self): return self.ref - #if self._get_ref_cache: - # return self._get_ref_cache - #ref = super(StructVarsizeNode, self).get_ref() - #typeval = self.db.repr_type(lltype.typeOf(self.value)) - #ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), - # ref, - # typeval) - #self._get_ref_cache = ref - #return ref - def get_pbcref(self, toptr): - """ Returns a reference as used per pbc. """ - return self.ref - #ref = self.ref - #p, c = lltype.parentlink(self.value) - #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) - #return ref + #def get_pbcref(self, toptr): + # """ Returns a reference as used per pbc. """ + # return self.ref From aft at codespeak.net Sat Oct 15 00:54:15 2005 From: aft at codespeak.net (aft at codespeak.net) Date: Sat, 15 Oct 2005 00:54:15 +0200 (CEST) Subject: [pypy-svn] r18593 - pypy/dist/pypy/module/Numeric Message-ID: <20051014225415.AD9B127B54@code1.codespeak.net> Author: aft Date: Sat Oct 15 00:54:03 2005 New Revision: 18593 Modified: pypy/dist/pypy/module/Numeric/__init__.py pypy/dist/pypy/module/Numeric/interp_numeric.py pypy/dist/pypy/module/Numeric/test_numeric.py Log: made import Numeric use new interp-space module, some simple tests to begin derivation of array type Modified: pypy/dist/pypy/module/Numeric/__init__.py ============================================================================== --- pypy/dist/pypy/module/Numeric/__init__.py (original) +++ pypy/dist/pypy/module/Numeric/__init__.py Sat Oct 15 00:54:03 2005 @@ -1,4 +1,4 @@ -from pypy.interpreter.mixedmodule import MixedModule +from pypy.interpreter.mixedmodule import MixedModule class Module(MixedModule): """An RPython reimplementation of the Numeric module @@ -12,6 +12,8 @@ 'Int' : "space.wrap('l')", # 'array' : 'interp_numeric.w_array', 'zeros' : 'interp_numeric.w_zeros', + 'nzeros' : 'interp_numeric.w_nzeros', + 'array' : 'interp_numeric.w_array', } ## 'CODESIZE': 'space.wrap(interp_sre.CODESIZE)', Modified: pypy/dist/pypy/module/Numeric/interp_numeric.py ============================================================================== --- pypy/dist/pypy/module/Numeric/interp_numeric.py (original) +++ pypy/dist/pypy/module/Numeric/interp_numeric.py Sat Oct 15 00:54:03 2005 @@ -1,3 +1,5 @@ + + from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import GetSetProperty, TypeDef from pypy.interpreter.typedef import interp_attrproperty, interp_attrproperty_w @@ -28,21 +30,19 @@ self.strides.append( stride ) self.strides.reverse() + def check_space_true(self, space, w_index): + if not space.is_true(space.isinstance( w_index, space.w_int )): + raise NotImplementedError + idx = space.unwrap( w_index ) + assert isinstance( idx, int ) + return idx + def descr___getitem__( self, space, w_index ): - if space.is_true(space.isinstance( w_index, space.w_int )): - idx = space.unwrap( w_index ) - assert isinstance( idx, int ) - return self.get_single_item( space, [ idx ] ) - raise NotImplementedError + return self.get_single_item( space, [ self.check_space_true( space, w_index)]) def descr___setitem__( self, space, w_index, w_value ): - if space.is_true(space.isinstance( w_index, space.w_int )): - idx = space.unwrap( w_index ) - assert isinstance( idx, int ) - return self.set_single_item( space, [ idx ], w_value ) - raise NotImplementedError + return self.set_single_item( space, [ self.check_space_true( space, w_index) ], w_value ) - def fget_shape( space, self ): return space.newtuple( [ self.space.wrap( i ) for i in self.dims ] ) @@ -97,7 +97,7 @@ __setitem__ = descr___setitem__, ) -W_Array_Float.typedef = TypeDef("W_Array_Float", W_Array.typedef, +W_Array_Float.typedef = TypeDef("W_Array_Float", W_Array.typedef, ) def w_zeros( space, w_dim_tuple, type_str ): @@ -109,3 +109,107 @@ raise OperationError( space.w_ValueError, space.wrap('Unknown type code') ) w_zeros.unwrap_spec = [ ObjSpace, W_Root, str ] + + +""" +""" +class W_NumericArray(Wrappable): + + def __init__(self, space, dims ): + self.space = space + assert isinstance(dims, list) + self.dims = dims + self.strides = [1] + self.base_object = None + self.base_offset = 0 # needed later for offseting into a shared storage + stride = 1 + for n in self.dims[:-1]: + stride *= n + self.strides.append( stride ) + self.strides.reverse() + + def check_space_true(self, space, w_index): + if not space.is_true(space.isinstance( w_index, space.w_int )): + raise NotImplementedError + idx = space.unwrap( w_index ) + assert isinstance( idx, int ) + return idx + + def descr___getitem__( self, space, w_index ): + return self.get_single_item( space, [ self.check_space_true( space, w_index)]) + + def descr___setitem__( self, space, w_index, w_value ): + return self.set_single_item( space, [ self.check_space_true( space, w_index) ], w_value ) + + def fget_shape( space, self ): + return space.newtuple( [ self.space.wrap( i ) for i in self.dims ] ) + + def fset_shape( space, self, w_tuple ): + pass + + def get_array_offset( self, idx_tuple ): + if len(idx_tuple)>len(self.dims): + # TODO raise OperationError + raise RuntimeError + idx = 0 + for i in range(len(idx_tuple)): + idx += self.strides[i]*idx_tuple[i] + return idx + + +class W_NumericArray_Float(W_NumericArray): + + def __init__(self, space, dims, storage=None ): + W_NumericArray.__init__(self, space, dims ) + storage_size = get_storage_size(dims) + self.storage = [] + if storage is not None: + assert isinstance(storage, list) + # TODO return proper exception here + assert len(storage)==storage_size + assert isinstance(storage[0], float) + self.storage = storage + else: + self.storage = [0.0]*storage_size + + def get_single_item( self, space, idx_tuple ): + if len(idx_tuple)!=len(self.dims): + # TODO raise OperationError or remove this and make it a pre-condition + raise RuntimeError + idx = self.get_array_offset( idx_tuple ) + return space.wrap( self.storage[idx] ) + + def set_single_item( self, space, idx_tuple, w_value ): + idx = self.get_array_offset( idx_tuple ) + value = space.float_w( w_value ) + self.storage[idx] = value + +descr___getitem__ = interp2app( W_NumericArray.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) +descr___setitem__ = interp2app( W_NumericArray.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) + + +W_NumericArray.typedef = TypeDef("W_NumericArray", + shape = GetSetProperty( W_NumericArray.fget_shape, cls=W_NumericArray), + __getitem__ = descr___getitem__, + __setitem__ = descr___setitem__, + ) + +W_NumericArray_Float.typedef = TypeDef("W_NumericArray_Float", W_NumericArray.typedef, + ) + +def w_nzeros( space, w_dim_tuple, type_str ): + dims = [] + for w_int in space.unpackiterable(w_dim_tuple): + dims.append( space.unwrap( w_int ) ) + if type_str == 'd': + return space.wrap(W_NumericArray_Float( space, dims )) + raise OperationError( space.w_ValueError, space.wrap('Unknown type code') ) + +w_nzeros.unwrap_spec = [ ObjSpace, W_Root, str ] + + +def w_array( space, w_dim_tuple): + raise OperationError( space.w_ValueError, space.wrap('Cannot create void array')) + +w_array.unwrap_spec = [ ObjSpace, W_Root ] + Modified: pypy/dist/pypy/module/Numeric/test_numeric.py ============================================================================== --- pypy/dist/pypy/module/Numeric/test_numeric.py (original) +++ pypy/dist/pypy/module/Numeric/test_numeric.py Sat Oct 15 00:54:03 2005 @@ -1,15 +1,45 @@ -from Numeric import zeros, Float +from Numeric import zeros,nzeros,array +from Numeric import Float -a = zeros( (3,2), Float ) -print a.shape -assert a.shape == (3,2) +class TestArray: + def test(self): + a = zeros( (3,2), Float ) + assert (3,2) == a.shape -b = zeros( (8,), Float ) + b = zeros( (8,), Float ) + assert 0.==b[1] + b[1]= 1. + assert 1.==b[1] -print b[1], b[2] -b[1] = 1. -print b[1], b[2] + def testZeros(self): + pass + +TestArray().test() +TestArray().testZeros() +#### Original test above. + +a=nzeros((2,7),Float) + +assert (2,7)== a.shape +b=nzeros((10,),Float) +assert 0.==b[2] +b[3]=555 +assert b[3]==555 + +def assertRaises(block,exception=Exception,shout='This should raise an exception'): + try: + block() + except exception: + pass + else: + assert False,shout + + +assertRaises(lambda :array(()),exception=ValueError) #this should fail + +a=array([1]) +#assert a[0]==1 last test broken... From rxe at codespeak.net Sat Oct 15 03:58:50 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Sat, 15 Oct 2005 03:58:50 +0200 (CEST) Subject: [pypy-svn] r18594 - in pypy/dist/pypy: interpreter objspace tool Message-ID: <20051015015850.B335127B54@code1.codespeak.net> Author: rxe Date: Sat Oct 15 03:58:46 2005 New Revision: 18594 Modified: pypy/dist/pypy/interpreter/interactive.py pypy/dist/pypy/objspace/trace.py pypy/dist/pypy/tool/traceconfig.py pypy/dist/pypy/tool/traceop.py Log: Give the trace object space some long overdue attention. Modified: pypy/dist/pypy/interpreter/interactive.py ============================================================================== --- pypy/dist/pypy/interpreter/interactive.py (original) +++ pypy/dist/pypy/interpreter/interactive.py Sat Oct 15 03:58:46 2005 @@ -178,7 +178,11 @@ # execute it self.settrace() - code.exec_code(self.space, self.w_globals, self.w_globals) + try: + code.exec_code(self.space, self.w_globals, self.w_globals) + finally: + if self.tracelevel: + self.space.unsettrace() self.checktrace() # run doit() in an exception-catching box @@ -208,22 +212,9 @@ if self.tracelevel == 0 and tracelevel > 0: trace.create_trace_space(s) + self.space.unsettrace() print "Tracing enabled" - - self.tracelevel = tracelevel - - def set_tracelevel(self, tracelevel): - # Disable tracing altogether? - from pypy.objspace import trace - - if self.tracelevel > 0 and tracelevel == 0: - self.space.reset_trace() - print self.get_banner() - - if self.tracelevel == 0 and tracelevel > 0: - trace.create_trace_space(self.space) - print self.get_banner() - + self.tracelevel = tracelevel Modified: pypy/dist/pypy/objspace/trace.py ============================================================================== --- pypy/dist/pypy/objspace/trace.py (original) +++ pypy/dist/pypy/objspace/trace.py Sat Oct 15 03:58:46 2005 @@ -3,10 +3,7 @@ in frames. """ -from __future__ import generators from pypy.tool import pydis -from pypy.tool.traceop import ResultPrinter -from pypy.interpreter.baseobjspace import ObjSpace # __________________________________________________________________________ # @@ -57,7 +54,8 @@ self.events = [] self.reentrant = True self.tracespace = tracespace - self.printer = ResultPrinter(**printer_options) + result_printer_clz = printer_options["result_printer_clz"] + self.printer = result_printer_clz(**printer_options) self._cache = {} def append(self, event): @@ -156,38 +154,28 @@ # __________________________________________________________________________ # -operations = None -def get_operations(): - global operations - if operations is None: - operations = dict([(r[0], r[0]) for r in ObjSpace.MethodTable]) - for name in ObjSpace.IrregularOpTable + ["get_and_call_function"]: - operations[name] = name - - # Remove list - for name in ["wrap", "unwrap", "interpclass_w"]: - if name in operations: - del operations[name] - return operations - -def create_trace_space(space, operations = None): - """ Will create a trace object space if no space supplied. Otherwise - will turn the supplied into a traceable space by extending its class.""" +def create_trace_space(space): + """ Will turn the supplied into a traceable space by extending its class.""" # Don't trace an already traceable space if hasattr(space, "__pypytrace__"): return space - - if operations is None: - operations = get_operations() class Trace(space.__class__): def __getattribute__(self, name): obj = super(Trace, self).__getattribute__(name) - if name in operations and not self._in_cache: - assert callable(obj) - obj = CallableTracer(self._result, name, obj) + if name in ["_result", "_in_cache", + "_tracing", "_config_options"]: + return obj + + if not self._tracing or self._in_cache: + return obj + + if name in self._config_options["operations"]: + assert callable(obj) + obj = CallableTracer(self._result, name, obj) + return obj def __pypytrace__(self): @@ -201,7 +189,11 @@ def settrace(self): self._result = TraceResult(self, **self._config_options) + self._tracing = True + def unsettrace(self): + self._tracing = False + def getresult(self): return self._result @@ -212,24 +204,25 @@ ec = ExecutionContextTracer(self._result, ec) return ec + # XXX Rename def reset_trace(self): """ Returns the class to it's original form. """ space.__class__ = space.__oldclass__ del space.__oldclass__ - for k in ["_result", "_in_cache", "_config_options"]: + for k in ["_result", "_in_cache", "_config_options", "_operations"]: if hasattr(self, k): delattr(self, k) - + trace_clz = type("Trace%s" % repr(space), (Trace,), {}) space.__oldclass__, space.__class__ = space.__class__, trace_clz - from pypy.tool.traceconfig import config as config_options - - # Avoid __getattribute__() woes - space._in_cache = 0 - space._config_options = config_options + # Do config + from pypy.tool.traceconfig import config + space._tracing = False space._result = None + space._in_cache = 0 + space._config_options = config space.settrace() return space Modified: pypy/dist/pypy/tool/traceconfig.py ============================================================================== --- pypy/dist/pypy/tool/traceconfig.py (original) +++ pypy/dist/pypy/tool/traceconfig.py Sat Oct 15 03:58:46 2005 @@ -1,6 +1,21 @@ """ Trace object space configuration options - set with __pytrace__=1 in py.py """ +from pypy.tool.traceop import ResultPrinter, ResultPrinterVerbose + +def get_operations_all(): + from pypy.interpreter.baseobjspace import ObjSpace + operations = dict([(r[0], r[0]) for r in ObjSpace.MethodTable]) + for name in ObjSpace.IrregularOpTable + ["get_and_call_function"]: + operations[name] = name + + # Remove list + for name in ["wrap", "unwrap", "interpclass_w"]: + if name in operations: + del operations[name] + + return operations + config = { # An optional filename to use for trace output. None is stdout "output_filename" : None, @@ -22,6 +37,14 @@ "indentor" : ' ', # Show wrapped values in bytecode - "show_wrapped_consts_bytecode" : True + "show_wrapped_consts_bytecode" : True, + + # Used to show realtive position in tree + "tree_pos_indicator" : "|-", + + "result_printer_clz" : ResultPrinter, + + "operations" : get_operations_all() } + Modified: pypy/dist/pypy/tool/traceop.py ============================================================================== --- pypy/dist/pypy/tool/traceop.py (original) +++ pypy/dist/pypy/tool/traceop.py Sat Oct 15 03:58:46 2005 @@ -5,10 +5,6 @@ import sys -def reversed(seq): - length = len(seq) - for index in range(length-1, -1, -1): - yield seq[index] class Stack(list): push = list.append @@ -22,16 +18,18 @@ except IndexError: return None -class ResultPrinter: +class ResultPrinter(object): def __init__(self, indentor = ' ', repr_type_simple = True, show_bytecode = True, output_filename = None, + tree_pos_indicator = "|-", show_hidden_applevel = False, recursive_operations = False, show_wrapped_consts_bytecode = True, + **kwds ): if output_filename is None: @@ -41,6 +39,7 @@ # Configurable stuff self.indentor = indentor + self.tree_pos_indicator = tree_pos_indicator self.show_bytecode = show_bytecode self.show_hidden_applevel = show_hidden_applevel self.recursive_operations = recursive_operations @@ -72,7 +71,7 @@ if indent_count: indent = indent_count - 1 assert (indent >= 0) - line = (self.indentor * indent) + "|-" + line + line = (self.indentor * indent) + self.tree_pos_indicator + line if new_line: self.last_line_was_new = True @@ -207,10 +206,33 @@ self.indent_state.pop() def get_last_frame(self): - for c, t, f in reversed(self.indent_state): + for c, t, f in self.indent_state[::-1]: if f is not None: return f +class ResultPrinterVerbose(ResultPrinter): + """ Puts result on same line """ + def print_op_enter(self, space, name, args): + if not self.valid_state(): + return + + s = " " * 4 + s += "%s" % name + s += "(" + ", ".join([self.repr_value(space, ii) for ii in args]) + ")" + self.print_line(s) + + def print_op_exc(self, name, exc, space): + if not self.valid_state(): + return + + if self.last_line_was_new: + s = " " * 4 + else: + s = " " + s += "x-> %s" % self.repr_value(space, exc) + + self.print_line(s) + def simple_repr(space, obj): res = repr(obj) @@ -239,8 +261,9 @@ # Special case - arguments if isinstance(obj, Arguments): args = [repr_value(space, ii) for ii in obj.arguments_w] - args += ["%s = %s" % (k, repr_value(space, v)) - for k, v in obj.kwds_w.items()] + if obj.kwds_w: + args += ["%s = %s" % (k, repr_value(space, v)) + for k, v in obj.kwds_w.items()] if not obj.w_stararg is None: args.append("*" + repr_value_complex(space, obj.w_stararg)) if not obj.w_starstararg is None: @@ -265,19 +288,17 @@ # __________________________________________________________________________ -def perform_trace(tspace, app_func, *args_w, **kwds_w): +def perform_trace(tspace, app_func, *args_w): from pypy.interpreter.gateway import app2interp from pypy.interpreter.argument import Arguments # Create our function func_gw = app2interp(app_func) - func = func_gw.get_function(tspace) - w_func = tspace.wrap(func) - args = Arguments(tspace, args_w, kwds_w) + w_func = func_gw.get_function(tspace) # Run the func in the trace space and return results tspace.settrace() - w_result = tspace.call_args(w_func, args) + w_result = tspace.call_function(w_func, *args_w) trace_result = tspace.getresult() tspace.settrace() return w_result, trace_result From afa at codespeak.net Sat Oct 15 10:23:14 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 10:23:14 +0200 (CEST) Subject: [pypy-svn] r18595 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051015082314.458A127B49@code1.codespeak.net> Author: afa Date: Sat Oct 15 10:23:11 2005 New Revision: 18595 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: socket module: converts exceptions into OperationErrors Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sat Oct 15 10:23:11 2005 @@ -4,8 +4,6 @@ from pypy.interpreter.gateway import W_Root from pypy.interpreter.gateway import ObjSpace, NoneNotWrapped -#w_socketerror = ??? - if sys.platform == 'win32': WIN32_ERROR_MESSAGES = { errno.WSAEINTR: "Interrupted system call", @@ -58,7 +56,7 @@ errno.WSAEDISCON: "Graceful shutdown in progress", # Resolver errors - # XXX replace by the values in winsock.h + # XXX Not exported by errno. Replace by the values in winsock.h # errno.WSAHOST_NOT_FOUND: "No such host is known", # errno.WSATRY_AGAIN: "Host not found, or server failed", # errno.WSANO_RECOVERY: "Unexpected server error encountered", @@ -76,9 +74,19 @@ assert isinstance(e, socket.error) errno = e.args[0] msg = socket_strerror(errno) - w_error = space.call_function(w_socketerror, + + w_module = space.getbuiltinmodule('_socket') + if isinstance(e, socket.gaierror): + w_error = space.getattr(w_module, space.wrap('gaierror')) + elif isinstance(e, socket.herror): + w_error = space.getattr(w_module, space.wrap('gaierror')) + else: + w_error = space.getattr(w_module, space.wrap('error')) + + w_error = space.call_function(w_error, space.wrap(errno), space.wrap(msg)) + return w_error def gethostname(space): """gethostname() -> string @@ -88,7 +96,7 @@ try: return space.wrap(socket.gethostname()) except socket.error, e: - return wrap_socketerror(space, e) + raise wrap_socketerror(space, e) gethostname.unwrap_spec = [ObjSpace] def gethostbyname(space, name): @@ -96,7 +104,10 @@ Return the IP address (a string of the form '255.255.255.255') for a host. """ - return space.wrap(socket.gethostbyname(name)) + try: + return space.wrap(socket.gethostbyname(name)) + except socket.error, e: + raise wrap_socketerror(space, e) gethostbyname.unwrap_spec = [ObjSpace, str] def gethostbyname_ex(space, name): @@ -105,7 +116,10 @@ Return the true host name, a list of aliases, and a list of IP addresses, for a host. The host argument is a string giving a host name or IP number. """ - return space.wrap(socket.gethostbyname_ex(name)) + try: + return space.wrap(socket.gethostbyname_ex(name)) + except socket.error, e: + raise wrap_socketerror(space, e) gethostbyname_ex.unwrap_spec = [ObjSpace, str] def gethostbyaddr(space, ip_num): @@ -114,7 +128,10 @@ Return the true host name, a list of aliases, and a list of IP addresses, for a host. The host argument is a string giving a host name or IP number. """ - return space.wrap(socket.gethostbyaddr(ip_num)) + try: + return space.wrap(socket.gethostbyaddr(ip_num)) + except socket.error, e: + raise wrap_socketerror(space, e) gethostbyaddr.unwrap_spec = [ObjSpace, str] def getservbyname(space, name, w_proto=NoneNotWrapped): @@ -124,10 +141,13 @@ The optional protocol name, if given, should be 'tcp' or 'udp', otherwise any protocol will match. """ - if w_proto is None: - return space.wrap(socket.getservbyname(name)) - else: - return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) + try: + if w_proto is None: + return space.wrap(socket.getservbyname(name)) + else: + return space.wrap(socket.getservbyname(name, space.str_w(w_proto))) + except socket.error, e: + raise wrap_socketerror(space, e) getservbyname.unwrap_spec = [ObjSpace, str, W_Root] def getservbyport(space, port, w_proto=NoneNotWrapped): @@ -137,10 +157,13 @@ The optional protocol name, if given, should be 'tcp' or 'udp', otherwise any protocol will match. """ - if w_proto is None: - return space.wrap(socket.getservbyport(port)) - else: - return space.wrap(socket.getservbyport(port, space.str_w(w_proto))) + try: + if w_proto is None: + return space.wrap(socket.getservbyport(port)) + else: + return space.wrap(socket.getservbyport(port, space.str_w(w_proto))) + except socket.error, e: + raise wrap_socketerror(space, e) getservbyport.unwrap_spec = [ObjSpace, int, W_Root] def getprotobyname(space, name): @@ -148,7 +171,10 @@ Return the protocol number for the named protocol. (Rarely used.) """ - return space.wrap(socket.getprotobyname(name)) + try: + return space.wrap(socket.getprotobyname(name)) + except socket.error, e: + raise wrap_socketerror(space, e) getprotobyname.unwrap_spec = [ObjSpace, str] def fromfd(space, fd, family, type, w_proto=NoneNotWrapped): @@ -157,10 +183,13 @@ Create a socket object from the given file descriptor. The remaining arguments are the same as for socket(). """ - if w_proto is None: - return space.wrap(socket.fromfd(fd, family, type)) - else: - return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto))) + try: + if w_proto is None: + return space.wrap(socket.fromfd(fd, family, type)) + else: + return space.wrap(socket.fromfd(fd, family, type, space.int_w(w_proto))) + except socket.error, e: + raise wrap_socketerror(space, e) fromfd.unwrap_spec = [ObjSpace, int, int, int, W_Root] def socketpair(space, w_family=NoneNotWrapped, w_type=NoneNotWrapped, w_proto=NoneNotWrapped): @@ -171,17 +200,20 @@ The arguments are the same as for socket() except the default family is AF_UNIX if defined on the platform; otherwise, the default is AF_INET. """ - if w_family is None: - return space.wrap(socket.socketpair()) - elif w_type is None: - return space.wrap(socket.socketpair(space.int_w(w_family))) - elif w_proto is None: - return space.wrap(socket.socketpair(space.int_w(w_family), - space.int_w(w_type))) - else: - return space.wrap(socket.socketpair(space.int_w(w_family), - space.int_w(w_type), - space.int_w(w_proto))) + try: + if w_family is None: + return space.wrap(socket.socketpair()) + elif w_type is None: + return space.wrap(socket.socketpair(space.int_w(w_family))) + elif w_proto is None: + return space.wrap(socket.socketpair(space.int_w(w_family), + space.int_w(w_type))) + else: + return space.wrap(socket.socketpair(space.int_w(w_family), + space.int_w(w_type), + space.int_w(w_proto))) + except socket.error, e: + raise wrap_socketerror(space, e) socketpair.unwrap_spec = [ObjSpace, W_Root, W_Root, W_Root] def ntohs(space, x): @@ -189,7 +221,10 @@ Convert a 16-bit integer from network to host byte order. """ - return space.wrap(socket.ntohs(x)) + try: + return space.wrap(socket.ntohs(x)) + except socket.error, e: + raise wrap_socketerror(space, e) ntohs.unwrap_spec = [ObjSpace, int] def ntohl(space, x): @@ -197,7 +232,10 @@ Convert a 32-bit integer from network to host byte order. """ - return space.wrap(socket.ntohl(x)) + try: + return space.wrap(socket.ntohl(x)) + except socket.error, e: + raise wrap_socketerror(space, e) ntohl.unwrap_spec = [ObjSpace, int] def htons(space, x): @@ -205,7 +243,10 @@ Convert a 16-bit integer from host to network byte order. """ - return space.wrap(socket.htons(x)) + try: + return space.wrap(socket.htons(x)) + except socket.error, e: + raise wrap_socketerror(space, e) htons.unwrap_spec = [ObjSpace, int] def htonl(space, x): @@ -213,7 +254,10 @@ Convert a 32-bit integer from host to network byte order. """ - return space.wrap(socket.htonl(x)) + try: + return space.wrap(socket.htonl(x)) + except socket.error, e: + raise wrap_socketerror(space, e) htonl.unwrap_spec = [ObjSpace, int] def inet_aton(space, ip): @@ -222,7 +266,10 @@ Convert an IP address in string format (123.45.67.89) to the 32-bit packed binary format used in low-level network functions. """ - return space.wrap(socket.inet_aton(ip)) + try: + return space.wrap(socket.inet_aton(ip)) + except socket.error, e: + raise wrap_socketerror(space, e) inet_aton.unwrap_spec = [ObjSpace, str] def inet_ntoa(space, packed): @@ -230,7 +277,10 @@ Convert an IP address from 32-bit packed binary format to string format """ - return space.wrap(socket.inet_ntoa(packed)) + try: + return space.wrap(socket.inet_ntoa(packed)) + except socket.error, e: + raise wrap_socketerror(space, e) inet_ntoa.unwrap_spec = [ObjSpace, str] def inet_pton(space, af, ip): @@ -239,7 +289,10 @@ Convert an IP address from string format to a packed string suitable for use with low-level network functions. """ - return space.wrap(socket.inet_pton(af, ip)) + try: + return space.wrap(socket.inet_pton(af, ip)) + except socket.error, e: + raise wrap_socketerror(space, e) inet_pton.unwrap_spec = [ObjSpace, int, str] def inet_ntop(space, af, packed): @@ -247,7 +300,10 @@ Convert a packed IP address of the given family to string format. """ - return space.wrap(socket.inet_ntop(af, packed)) + try: + return space.wrap(socket.inet_ntop(af, packed)) + except socket.error, e: + raise wrap_socketerror(space, e) inet_ntop.unwrap_spec = [ObjSpace, int, str] def getaddrinfo(space, w_host, w_port, family=0, socktype=0, proto=0, flags=0): @@ -265,7 +321,10 @@ else: port = space.str_w(w_port) - return space.wrap(socket.getaddrinfo(host, port, family, socktype, proto, flags)) + try: + return space.wrap(socket.getaddrinfo(host, port, family, socktype, proto, flags)) + except socket.error, e: + raise wrap_socketerror(space, e) getaddrinfo.unwrap_spec = [ObjSpace, W_Root, W_Root, int, int, int, int] def getnameinfo(space, w_sockaddr, flags): @@ -273,7 +332,10 @@ Get host and port for a sockaddr.""" sockaddr = space.unwrap(w_sockaddr) - return space.wrap(socket.getnameinfo(sockaddr, flags)) + try: + return space.wrap(socket.getnameinfo(sockaddr, flags)) + except socket.error, e: + raise wrap_socketerror(space, e) getnameinfo.unwrap_spec = [ObjSpace, W_Root, int] def getdefaulttimeout(space): @@ -296,3 +358,4 @@ timeout = space.unwrap(w_timeout) return space.wrap(socket.setdefaulttimeout(timeout)) setdefaulttimeout.unwrap_spec = [ObjSpace, W_Root] + Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Sat Oct 15 10:23:11 2005 @@ -148,7 +148,7 @@ w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info - py.test.skip("Too long...") + py.test.skip("Unicode conversion is too slow") w_l = space.appexec([w_socket, space.wrap(unicode(host)), space.wrap(port)], "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info From arigo at codespeak.net Sat Oct 15 10:28:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 10:28:23 +0200 (CEST) Subject: [pypy-svn] r18597 - pypy/dist/pypy/translator/goal Message-ID: <20051015082823.DC69C27B49@code1.codespeak.net> Author: arigo Date: Sat Oct 15 10:28:21 2005 New Revision: 18597 Removed: pypy/dist/pypy/translator/goal/targetrichards.py Log: Remove what is probably a file checked in by error From arigo at codespeak.net Sat Oct 15 10:29:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 10:29:23 +0200 (CEST) Subject: [pypy-svn] r18598 - pypy/dist/pypy/translator/goal Message-ID: <20051015082923.DF57927B49@code1.codespeak.net> Author: arigo Date: Sat Oct 15 10:29:20 2005 New Revision: 18598 Added: pypy/dist/pypy/translator/goal/targetrichards.py - copied unchanged from r18431, pypy/dist/pypy/translator/goal/targetrichards.py Log: Restored revision 18431 From mwh at codespeak.net Sat Oct 15 10:54:43 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 10:54:43 +0200 (CEST) Subject: [pypy-svn] r18599 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20051015085443.10EEA27B44@code1.codespeak.net> Author: mwh Date: Sat Oct 15 10:54:41 2005 New Revision: 18599 Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py Log: deindent Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Sat Oct 15 10:54:41 2005 @@ -379,13 +379,13 @@ return v class __extend__(pairtype(ClassesPBCRepr, ClassesPBCRepr)): - def convert_from_to((r_clspbc1, r_clspbc2), v, llops): - # this check makes sense because both source and dest repr are ClassesPBCRepr - if r_clspbc1.lowleveltype == r_clspbc2.lowleveltype: - return v - if r_clspbc1.lowleveltype is Void: - return inputconst(r_clspbc2, r_clspbc1.s_pbc.const) - return NotImplemented + def convert_from_to((r_clspbc1, r_clspbc2), v, llops): + # this check makes sense because both source and dest repr are ClassesPBCRepr + if r_clspbc1.lowleveltype == r_clspbc2.lowleveltype: + return v + if r_clspbc1.lowleveltype is Void: + return inputconst(r_clspbc2, r_clspbc1.s_pbc.const) + return NotImplemented From afa at codespeak.net Sat Oct 15 11:02:43 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 11:02:43 +0200 (CEST) Subject: [pypy-svn] r18600 - pypy/dist/pypy/module/_socket Message-ID: <20051015090243.EFBD627B48@code1.codespeak.net> Author: afa Date: Sat Oct 15 11:02:42 2005 New Revision: 18600 Modified: pypy/dist/pypy/module/_socket/__init__.py pypy/dist/pypy/module/_socket/app_socket.py pypy/dist/pypy/module/_socket/interp_socket.py Log: (valentino, afa) moved socket.(set|get)defaulttimeout to applevel Modified: pypy/dist/pypy/module/_socket/__init__.py ============================================================================== --- pypy/dist/pypy/module/_socket/__init__.py (original) +++ pypy/dist/pypy/module/_socket/__init__.py Sat Oct 15 11:02:42 2005 @@ -9,6 +9,8 @@ 'herror' : 'app_socket.herror', 'gaierror' : 'app_socket.gaierror', 'timeout' : 'app_socket.timeout', + 'setdefaulttimeout' : 'app_socket.setdefaulttimeout', + 'getdefaulttimeout' : 'app_socket.getdefaulttimeout', } interpleveldefs = { @@ -20,7 +22,6 @@ fromfd socketpair ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop getaddrinfo getnameinfo - getdefaulttimeout setdefaulttimeout """.split(): if hasattr(_socket, name): Modified: pypy/dist/pypy/module/_socket/app_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/app_socket.py (original) +++ pypy/dist/pypy/module/_socket/app_socket.py Sat Oct 15 11:02:42 2005 @@ -1,7 +1,10 @@ """Implementation module for socket operations. +NOT_RPYTHON See the socket module for documentation.""" +defaulttimeout = -1 # Default timeout for new sockets + class error(Exception): pass @@ -18,3 +21,21 @@ pass socket = SocketType + +def setdefaulttimeout(timeout): + if timeout is None: + timeout = -1.0 + else: + if timeout < 0.0: + raise ValueError, "Timeout value out of range" + + global defaulttimeout + defaulttimeout = timeout + +def getdefaulttimeout(): + timeout = defaulttimeout + + if timeout < 0.0: + return None + else: + return timeout Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sat Oct 15 11:02:42 2005 @@ -338,24 +338,3 @@ raise wrap_socketerror(space, e) getnameinfo.unwrap_spec = [ObjSpace, W_Root, int] -def getdefaulttimeout(space): - """getdefaulttimeout() -> timeout - - Returns the default timeout in floating seconds for new socket objects. - A value of None indicates that new socket objects have no timeout. - When the socket module is first imported, the default is None. - """ - return space.wrap(socket.getdefaulttimeout()) -getdefaulttimeout.unwrap_spec = [ObjSpace] - -def setdefaulttimeout(space, w_timeout): - """setdefaulttimeout(timeout) - - Set the default timeout in floating seconds for new socket objects. - A value of None indicates that new socket objects have no timeout. - When the socket module is first imported, the default is None. - """ - timeout = space.unwrap(w_timeout) - return space.wrap(socket.setdefaulttimeout(timeout)) -setdefaulttimeout.unwrap_spec = [ObjSpace, W_Root] - From cfbolz at codespeak.net Sat Oct 15 11:42:03 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 15 Oct 2005 11:42:03 +0200 (CEST) Subject: [pypy-svn] r18601 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051015094203.C573C27B48@code1.codespeak.net> Author: cfbolz Date: Sat Oct 15 11:42:01 2005 New Revision: 18601 Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: failing translation test??? Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/l3interp.py Sat Oct 15 11:42:01 2005 @@ -21,7 +21,7 @@ assert len(args) == 0, "not implemented, XXX" link = self.graph.startlink # self.fill_input_arg(... - while type(link) == model.Link: + while type(link) is model.Link: link = self.eval_block(link.target) self.copy_link_vars(link) return link @@ -37,6 +37,8 @@ def copy_link_vars(self, link): + if not len(link.move_int_registers): + return for i in range(0, len(link.move_int_registers), 2): source = link.move_int_registers[i] target = link.move_int_registers[i + 1] Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sat Oct 15 11:42:01 2005 @@ -1,7 +1,10 @@ from pypy.rpython.l3interp import l3interp from pypy.rpython.l3interp import model +from pypy.translator.c.test.test_genc import compile +from pypy.translator.translator import Translator +from pypy.annotation import policy -def test_very_simple(): +def eval_seven(): op = model.Operation(l3interp.LLFrame.op_int_add, 0, [-1, -2]) returnlink = model.ReturnLink(None, []) block = model.Block([], model.ONE_EXIT, [returnlink]) @@ -12,6 +15,19 @@ g = model.Globals() g.graphs = [graph] interp = l3interp.LLInterpreter() - result = interp.eval_graph_int(graph, []) + return interp.eval_graph_int(graph, []) + + +def test_very_simple(): + result = eval_seven() assert result == 7 - + +def test_very_simple_translated(): + t = Translator(eval_seven) + pol = policy.AnnotatorPolicy() + pol.allow_someobjects = False + t.annotate([], policy=pol) + t.specialize() + t.view() + fn = t.ccompile() + From arigo at codespeak.net Sat Oct 15 11:45:57 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 11:45:57 +0200 (CEST) Subject: [pypy-svn] r18602 - in pypy/dist/pypy/interpreter: astcompiler test Message-ID: <20051015094557.BDB9227B48@code1.codespeak.net> Author: arigo Date: Sat Oct 15 11:45:56 2005 New Revision: 18602 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/interpreter/test/test_compiler.py Log: bug fix: set co_firstlineno even if the function body is empty. Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Sat Oct 15 11:45:56 2005 @@ -559,6 +559,7 @@ """Arrange the blocks in order and resolve jumps""" assert self.stage == CONV self.insts = insts = [] + firstline = 0 pc = 0 begin = {} end = {} @@ -616,6 +617,8 @@ pc = pc + 3 else: insts.append(inst) + if firstline == 0: + firstline = inst.intval end[b] = pc pc = 0 @@ -627,6 +630,7 @@ inst.intval = offset else: inst.intval = abspos + self.firstline = firstline self.stage = FLAT hasjrel = {} @@ -770,7 +774,7 @@ def makeByteCode(self): assert self.stage == FLAT - self.lnotab = lnotab = LineAddrTable() + self.lnotab = lnotab = LineAddrTable(self.firstline) for t in self.insts: opname = t.op if self._debug: @@ -820,7 +824,7 @@ self.names, self.varnames, self.filename, self.name, - self.lnotab.firstline, + self.firstline, self.lnotab.getTable(), self.freevars, self.cellvars @@ -860,11 +864,11 @@ compile.c for the delicate details. """ - def __init__(self): + def __init__(self, firstline): self.code = [] self.codeOffset = 0 - self.firstline = 0 - self.lastline = 0 + self.firstline = firstline + self.lastline = firstline self.lastoff = 0 self.lnotab = [] @@ -879,36 +883,32 @@ self.codeOffset = self.codeOffset + 3 def nextLine(self, lineno): - if self.firstline == 0: - self.firstline = lineno + # compute deltas + addr = self.codeOffset - self.lastoff + line = lineno - self.lastline + # Python assumes that lineno always increases with + # increasing bytecode address (lnotab is unsigned char). + # Depending on when SET_LINENO instructions are emitted + # this is not always true. Consider the code: + # a = (1, + # b) + # In the bytecode stream, the assignment to "a" occurs + # after the loading of "b". This works with the C Python + # compiler because it only generates a SET_LINENO instruction + # for the assignment. + if line >= 0: + push = self.lnotab.append + while addr > 255: + push(255); push(0) + addr -= 255 + while line > 255: + push(addr); push(255) + line -= 255 + addr = 0 + if addr > 0 or line > 0: + push(addr); push(line) self.lastline = lineno - else: - # compute deltas - addr = self.codeOffset - self.lastoff - line = lineno - self.lastline - # Python assumes that lineno always increases with - # increasing bytecode address (lnotab is unsigned char). - # Depending on when SET_LINENO instructions are emitted - # this is not always true. Consider the code: - # a = (1, - # b) - # In the bytecode stream, the assignment to "a" occurs - # after the loading of "b". This works with the C Python - # compiler because it only generates a SET_LINENO instruction - # for the assignment. - if line >= 0: - push = self.lnotab.append - while addr > 255: - push(255); push(0) - addr -= 255 - while line > 255: - push(addr); push(255) - line -= 255 - addr = 0 - if addr > 0 or line > 0: - push(addr); push(line) - self.lastline = lineno - self.lastoff = self.codeOffset + self.lastoff = self.codeOffset def getCode(self): return ''.join(self.code) 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 Sat Oct 15 11:45:56 2005 @@ -318,7 +318,26 @@ ex = e.value ex.normalize_exception(space) assert ex.match(space, space.w_SyntaxError) - + + def test_firstlineno(self): + snippet = str(py.code.Source(r''' + def f(): "line 2" + if 3 and \ + (4 and + 5): + def g(): "line 6" + fline = f.func_code.co_firstlineno + gline = g.func_code.co_firstlineno + ''')) + code = self.compiler.compile(snippet, '', 'exec', 0) + space = self.space + w_d = space.newdict([]) + code.exec_code(space, w_d, w_d) + w_fline = space.getitem(w_d, space.wrap('fline')) + w_gline = space.getitem(w_d, space.wrap('gline')) + assert space.int_w(w_fline) == 2 + #IN-PROGRESS assert space.int_w(w_gline) == 6 + class TestECCompiler(BaseTestCompiler): def setup_method(self, method): self.compiler = self.space.getexecutioncontext().compiler From mwh at codespeak.net Sat Oct 15 11:49:08 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 11:49:08 +0200 (CEST) Subject: [pypy-svn] r18603 - in pypy/dist/pypy/rpython: . lltypesystem Message-ID: <20051015094908.A53D627B48@code1.codespeak.net> Author: mwh Date: Sat Oct 15 11:49:06 2005 New Revision: 18603 Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/lltypesystem/rpbc.py pypy/dist/pypy/rpython/rpbc.py Log: (boria, mwh) * moved most of ClassesPBCRepr from rpython.lltypesystem.rpbc back to rpython.rpbc renamed as AbstractClassesPBCRepr. * renamed rpython.lltypesystem.rclass.TYPEPTR to CLASSTYPE Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Sat Oct 15 11:49:06 2005 @@ -52,18 +52,18 @@ # there's also a nongcobject OBJECT_VTABLE = ForwardReference() -TYPEPTR = Ptr(OBJECT_VTABLE) -OBJECT = GcStruct('object', ('typeptr', TYPEPTR)) +CLASSTYPE = Ptr(OBJECT_VTABLE) +OBJECT = GcStruct('object', ('typeptr', CLASSTYPE)) OBJECTPTR = Ptr(OBJECT) OBJECT_VTABLE.become(Struct('object_vtable', - ('parenttypeptr', TYPEPTR), + ('parenttypeptr', CLASSTYPE), ('subclassrange_min', Signed), ('subclassrange_max', Signed), ('rtti', Ptr(RuntimeTypeInfo)), ('name', Ptr(Array(Char))), ('instantiate', Ptr(FuncType([], OBJECTPTR))))) # non-gc case -NONGCOBJECT = Struct('nongcobject', ('typeptr', TYPEPTR)) +NONGCOBJECT = Struct('nongcobject', ('typeptr', CLASSTYPE)) NONGCOBJECTPTR = Ptr(OBJECT) def cast_vtable_to_typeptr(vtable): @@ -496,7 +496,7 @@ vlist = [inputconst(Void, flavor)] + vlist vptr = llops.genop(mallocop, vlist, resulttype = Ptr(self.object_type)) # xxx flavor - ctypeptr = inputconst(TYPEPTR, self.rclass.getvtable()) + ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable()) self.setfield(vptr, '__class__', ctypeptr, llops) # initialize instance attributes from their defaults from the class if self.classdef is not None: Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Sat Oct 15 11:49:06 2005 @@ -11,7 +11,8 @@ from pypy.rpython import rtuple from pypy.rpython.rpbc import SingleFrozenPBCRepr, getsignature, samesig,\ commonbase, allattributenames, get_access_set,\ - MultiplePBCRepr, FunctionsPBCRepr + MultiplePBCRepr, FunctionsPBCRepr, \ + AbstractClassesPBCRepr from pypy.rpython.lltypesystem import rclass from pypy.tool.sourcetools import has_varargs @@ -273,45 +274,10 @@ # ____________________________________________________________ -class ClassesPBCRepr(Repr): +class ClassesPBCRepr(AbstractClassesPBCRepr): """Representation selected for a PBC of class(es).""" - def __init__(self, rtyper, s_pbc): - self.rtyper = rtyper - self.s_pbc = s_pbc - if None in s_pbc.prebuiltinstances: - raise TyperError("unsupported: variable of type " - "class-pointer or None") - if s_pbc.is_constant(): - self.lowleveltype = Void - else: - self.lowleveltype = rclass.TYPEPTR - self._access_set = None - self._class_repr = None - - def get_access_set(self): - if self._access_set is None: - access_sets = self.rtyper.annotator.getpbcaccesssets() - classes = self.s_pbc.prebuiltinstances.keys() - _, _, access = access_sets.find(classes[0]) - for obj in classes[1:]: - _, _, access1 = access_sets.find(obj) - assert access1 is access # XXX not implemented - commonbase = access.commonbase - self._class_repr = rclass.getclassrepr(self.rtyper, commonbase) - self._access_set = access - return self._access_set - - def get_class_repr(self): - self.get_access_set() - return self._class_repr - - def convert_const(self, cls): - if cls not in self.s_pbc.prebuiltinstances: - raise TyperError("%r not in %r" % (cls, self)) - if self.lowleveltype is Void: - return cls - return rclass.get_type_repr(self.rtyper).convert_const(cls) + # no __init__ here, AbstractClassesPBCRepr.__init__ is good enough def rtype_simple_call(self, hop): return self.redispatch_call(hop, call_args=False) @@ -359,18 +325,6 @@ hop2.dispatch() return v_instance - def rtype_getattr(self, hop): - if hop.s_result.is_constant(): - return hop.inputconst(hop.r_result, hop.s_result.const) - else: - attr = hop.args_s[1].const - vcls, vattr = hop.inputargs(self, Void) - return self.getfield(vcls, attr, hop.llops) - - def getfield(self, vcls, attr, llops): - access_set = self.get_access_set() - class_repr = self.get_class_repr() - return class_repr.getpbcfield(vcls, access_set, attr, llops) class __extend__(pairtype(ClassesPBCRepr, rclass.AbstractClassRepr)): def convert_from_to((r_clspbc, r_cls), v, llops): Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Sat Oct 15 11:49:06 2005 @@ -293,6 +293,76 @@ # ____________________________________________________________ +class AbstractClassesPBCRepr(Repr): + """Representation selected for a PBC of class(es).""" + + def __init__(self, rtyper, s_pbc): + self.rtyper = rtyper + self.s_pbc = s_pbc + if None in s_pbc.prebuiltinstances: + raise TyperError("unsupported: variable of type " + "class-pointer or None") + if s_pbc.is_constant(): + self.lowleveltype = Void + else: + self.lowleveltype = rtyper.type_system.rclass.CLASSTYPE + self._access_set = None + self._class_repr = None + + def get_access_set(self): + if self._access_set is None: + access_sets = self.rtyper.annotator.getpbcaccesssets() + classes = self.s_pbc.prebuiltinstances.keys() + _, _, access = access_sets.find(classes[0]) + for obj in classes[1:]: + _, _, access1 = access_sets.find(obj) + assert access1 is access # XXX not implemented + commonbase = access.commonbase + self._class_repr = rclass.getclassrepr(self.rtyper, commonbase) + self._access_set = access + return self._access_set + + def get_class_repr(self): + self.get_access_set() + return self._class_repr + + def convert_const(self, cls): + if cls not in self.s_pbc.prebuiltinstances: + raise TyperError("%r not in %r" % (cls, self)) + if self.lowleveltype is Void: + return cls + return rclass.get_type_repr(self.rtyper).convert_const(cls) + + def rtype_getattr(self, hop): + if hop.s_result.is_constant(): + return hop.inputconst(hop.r_result, hop.s_result.const) + else: + attr = hop.args_s[1].const + vcls, vattr = hop.inputargs(self, Void) + return self.getfield(vcls, attr, hop.llops) + + def getfield(self, vcls, attr, llops): + access_set = self.get_access_set() + class_repr = self.get_class_repr() + return class_repr.getpbcfield(vcls, access_set, attr, llops) + +class __extend__(pairtype(AbstractClassesPBCRepr, rclass.AbstractClassRepr)): + def convert_from_to((r_clspbc, r_cls), v, llops): + if r_cls.lowleveltype != r_clspbc.lowleveltype: + return NotImplemented # good enough for now + return v + +class __extend__(pairtype(AbstractClassesPBCRepr, AbstractClassesPBCRepr)): + def convert_from_to((r_clspbc1, r_clspbc2), v, llops): + # this check makes sense because both source and dest repr are ClassesPBCRepr + if r_clspbc1.lowleveltype == r_clspbc2.lowleveltype: + return v + if r_clspbc1.lowleveltype is Void: + return inputconst(r_clspbc2, r_clspbc1.s_pbc.const) + return NotImplemented + +# ____________________________________________________________ + def getsignature(rtyper, func): f = rtyper.getcallable(func) graph = rtyper.type_system_deref(f).graph From hpk at codespeak.net Sat Oct 15 11:54:49 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 15 Oct 2005 11:54:49 +0200 (CEST) Subject: [pypy-svn] r18604 - pypy/extradoc/planning Message-ID: <20051015095449.5A9AB27B49@code1.codespeak.net> Author: hpk Date: Sat Oct 15 11:54:47 2005 New Revision: 18604 Added: pypy/extradoc/planning/ pypy/extradoc/planning/phase2.txt (contents, props changed) Log: new directory "planning" in extradoc to have a more clear view on planned things regarding technical tasks and EU tasks etc. also added a first _rough_ draft planning regarding phase 2 related work (mostly seen from the EU perspective) for the saturday afternoon _mostly technical_ planning meeting to be continued by Bea and others i guess Added: pypy/extradoc/planning/phase2.txt ============================================================================== --- (empty file) +++ pypy/extradoc/planning/phase2.txt Sat Oct 15 11:54:47 2005 @@ -0,0 +1,100 @@ + +Rough preparation draft for saturday-afternoon meeting Paris +------------------------------------------------------------- + +sprints & conferences +------------------------- + +- 8th December Calibre/agile development workshop in + Bruxelles, Bea, Holger, Alastair attending (or maybe + just two persons). Bea coordinates. + +- December sprint: a sprint around bruxelles might make sense, + holger is checking with bruxelles and Louvain-la-neuve + (near bruxelles) people for a sprint beginning of + december. Bea is checking with Mallorca/Barcelona + regarding the same time frame. Nothing definitive + yet, alas! Do we have a double-fallback? + Meeting in Sweden? + +- more sprint planning: + + end january next sprint (mallorca/barcelona), + february around PyCon (27th-XXX) (Dallas, Texas) + beginning march romania or switzerland (bern?, swiss italian or leysin?) + end of april Japan (Bea is investigating dates & location) + June, EuroPython (CERN, switzerland, michael/holger?) + August, Ireland (through Bea contacts) + October, ... + +- conference planning: + + HALF-FIXED: CCC 27th-30th December Berlin (pypy technical talk accepted, + non-technical talk pending, may be unlikely, holger is keeping + contact) + + FIXED: Solution Linux 2006 (31st Januray-2nd Feb): + Logilab will present PyPy in the "free software models" track. + + OPEN: PyCon, 24th-26th Feburary: Holger wants to submit one or two proposals + and go there, also doing a py lib and/or pypy-sprint. Note that + sprints are scheduled after the conf. + DEADLINE: 30th October (in two weeks!) + + OPEN: OOPSLA? DEADLINE? + + OPEN: XP-conferences? DEADLINES? + +pypy technical task planning +---------------------------------- + +see paris-2005-possible-tasks.txt +- full compiler/parser integration + +- pypy-sync meetings should constantly track/amend/modify those + technical tasks and in general focus on technical issues + NOTE though: pypy-sync cannot focus too much on EU requirements + because it's a more open/community forum. + +EU-related Workpackage planning planning phase 2 +------------------------------------------------- + +- WP09 and WP10 done and coordinated by logilab/dfki + people. they should update the rest of us regarding + planning and also communicate regarding + possible related sprint topics. + +- WP02 dev infrastructure is in merlinux responsibility, + should also suggest sprint topics (considering e.g. + a py lib sprint at PyCon ...) + +- other WPs in phase 2 are probably more generally in + common responsibility (like WP04/WP05) with the lead + partner taking special responsibility (towards the EU): + + - WP03 (HHU) synchronisation CPython + - WP06 (HHU) core optimisations + - WP07 (tismerysoft) translator optimisations + - WP08 (Strakt) dynamic optimisations + - WP14 (Changemaker) dissemination/project representation + + open: + + - WP05: left over work for Impara (when they get accepted)? + + +EU-related report planning +------------------------------------------------- + +people and co-reviewers (lead parnter coordinating, +technical board evaluating overall consistency) + +D04.1 Partial Python Impl: +D04.2 Complete Python Impl: +D04.3 Parser report: +D04.4 Release PyPy-research-tool: + +D05.1 ... + +... + From adim at codespeak.net Sat Oct 15 12:06:00 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Sat, 15 Oct 2005 12:06:00 +0200 (CEST) Subject: [pypy-svn] r18606 - in pypy: dist/lib-python/modified-2.4.1/test testresult/adim@eusebius.local Message-ID: <20051015100600.57A5427B49@code1.codespeak.net> Author: adim Date: Sat Oct 15 12:05:57 2005 New Revision: 18606 Added: pypy/testresult/adim at eusebius.local/ pypy/testresult/adim at eusebius.local/test_descr.txt (contents, props changed) pypy/testresult/adim at eusebius.local/test_future.txt (contents, props changed) Modified: pypy/dist/lib-python/modified-2.4.1/test/test_descr.py Log: (arre, adim) removed tests using xxsubtype (doesn't make sense in PyPy) Modified: pypy/dist/lib-python/modified-2.4.1/test/test_descr.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_descr.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_descr.py Sat Oct 15 12:05:57 2005 @@ -511,86 +511,6 @@ vereq(repr(a), "234.5") vereq(a.prec, 12) -def spamlists(): - if verbose: print "Testing spamlist operations..." - import copy, xxsubtype as spam - def spamlist(l, memo=None): - import xxsubtype as spam - return spam.spamlist(l) - # This is an ugly hack: - copy._deepcopy_dispatch[spam.spamlist] = spamlist - - testbinop(spamlist([1]), spamlist([2]), spamlist([1,2]), "a+b", "__add__") - testbinop(spamlist([1,2,3]), 2, 1, "b in a", "__contains__") - testbinop(spamlist([1,2,3]), 4, 0, "b in a", "__contains__") - testbinop(spamlist([1,2,3]), 1, 2, "a[b]", "__getitem__") - testternop(spamlist([1,2,3]), 0, 2, spamlist([1,2]), - "a[b:c]", "__getslice__") - testsetop(spamlist([1]), spamlist([2]), spamlist([1,2]), - "a+=b", "__iadd__") - testsetop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*=b", "__imul__") - testunop(spamlist([1,2,3]), 3, "len(a)", "__len__") - testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "a*b", "__mul__") - testbinop(spamlist([1,2]), 3, spamlist([1,2,1,2,1,2]), "b*a", "__rmul__") - testset2op(spamlist([1,2]), 1, 3, spamlist([1,3]), "a[b]=c", "__setitem__") - testset3op(spamlist([1,2,3,4]), 1, 3, spamlist([5,6]), - spamlist([1,5,6,4]), "a[b:c]=d", "__setslice__") - # Test subclassing - class C(spam.spamlist): - def foo(self): return 1 - a = C() - vereq(a, []) - vereq(a.foo(), 1) - a.append(100) - vereq(a, [100]) - vereq(a.getstate(), 0) - a.setstate(42) - vereq(a.getstate(), 42) - -def spamdicts(): - if verbose: print "Testing spamdict operations..." - import copy, xxsubtype as spam - def spamdict(d, memo=None): - import xxsubtype as spam - sd = spam.spamdict() - for k, v in d.items(): sd[k] = v - return sd - # This is an ugly hack: - copy._deepcopy_dispatch[spam.spamdict] = spamdict - - testbinop(spamdict({1:2}), spamdict({2:1}), -1, "cmp(a,b)", "__cmp__") - testbinop(spamdict({1:2,3:4}), 1, 1, "b in a", "__contains__") - testbinop(spamdict({1:2,3:4}), 2, 0, "b in a", "__contains__") - testbinop(spamdict({1:2,3:4}), 1, 2, "a[b]", "__getitem__") - d = spamdict({1:2,3:4}) - l1 = [] - for i in d.keys(): l1.append(i) - l = [] - for i in iter(d): l.append(i) - vereq(l, l1) - l = [] - for i in d.__iter__(): l.append(i) - vereq(l, l1) - l = [] - for i in type(spamdict({})).__iter__(d): l.append(i) - vereq(l, l1) - straightd = {1:2, 3:4} - spamd = spamdict(straightd) - testunop(spamd, 2, "len(a)", "__len__") - testunop(spamd, repr(straightd), "repr(a)", "__repr__") - testset2op(spamdict({1:2,3:4}), 2, 3, spamdict({1:2,2:3,3:4}), - "a[b]=c", "__setitem__") - # Test subclassing - class C(spam.spamdict): - def foo(self): return 1 - a = C() - vereq(a.items(), []) - vereq(a.foo(), 1) - a['foo'] = 'bar' - vereq(a.items(), [('foo', 'bar')]) - vereq(a.getstate(), 0) - a.setstate(100) - vereq(a.getstate(), 100) def pydicts(): if verbose: print "Testing Python subclass of dict..." @@ -1493,19 +1413,6 @@ else: raise TestFailed, "classmethod should check for callability" -def classmethods_in_c(): - if verbose: print "Testing C-based class methods..." - import xxsubtype as spam - a = (1, 2, 3) - d = {'abc': 123} - x, a1, d1 = spam.spamlist.classmeth(*a, **d) - veris(x, spam.spamlist) - vereq(a, a1) - vereq(d, d1) - x, a1, d1 = spam.spamlist().classmeth(*a, **d) - veris(x, spam.spamlist) - vereq(a, a1) - vereq(d, d1) def staticmethods(): if verbose: print "Testing static methods..." @@ -1524,19 +1431,6 @@ vereq(d.foo(1), (d, 1)) vereq(D.foo(d, 1), (d, 1)) -def staticmethods_in_c(): - if verbose: print "Testing C-based static methods..." - import xxsubtype as spam - a = (1, 2, 3) - d = {"abc": 123} - x, a1, d1 = spam.spamlist.staticmeth(*a, **d) - veris(x, None) - vereq(a, a1) - vereq(d, d1) - x, a1, d2 = spam.spamlist().staticmeth(*a, **d) - veris(x, None) - vereq(a, a1) - vereq(d, d1) def classic(): if verbose: print "Testing classic classes..." @@ -4000,8 +3894,8 @@ longs, floats, complexes, - spamlists, - spamdicts, + # spamlists, + # spamdicts, pydicts, pylists, metaclass, @@ -4018,9 +3912,9 @@ dynamics, errors, classmethods, - classmethods_in_c, + # classmethods_in_c, staticmethods, - staticmethods_in_c, + # staticmethods_in_c, classic, compattr, newslot, Added: pypy/testresult/adim at eusebius.local/test_descr.txt ============================================================================== --- (empty file) +++ pypy/testresult/adim at eusebius.local/test_descr.txt Sat Oct 15 12:05:57 2005 @@ -0,0 +1,421 @@ +Content-Type: multipart/mixed; boundary="===============0101701468==" +MIME-Version: 1.0 +execution-time: 1891.00934291 +exit status: 1 +fspath: /Users/adim/var/pypy-dist/lib-python/modified-2.4.1/test/test_descr.py +options: ['oldstyle', 'core'] +outcome: ERR +platform: darwin +pypy-revision: 18595 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Sat Oct 15 10:38:53 2005 +testreport-version: 1.1 +timeout: 3600.0 +userhost: adim at eusebius.local +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============0101701468== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +**************************************** +Testing weakref segfault... +--> weakref_segfault FAILURE(0/88) No module named _weakref +**************************************** +Testing SF bug 551412 ... +Testing SF bug 570483... +--> do_this_first OK(1/88) +**************************************** +--> class_docstrings OK(2/88) +**************************************** +Testing list operations... +checking a+b +checking b in a +checking b in a +checking a[b] +checking a[b:c] +--> lists FAILURE(2/88) type object 'list' has no attribute '__getslice__' +**************************************** +Testing dict operations... +checking cmp(a,b) +--> dicts FAILURE(2/88) type object 'dict' has no attribute '__cmp__' +**************************************** +Testing dict constructor ... +--> dict_constructor OK(3/88) +**************************************** +Testing dir() ... +--> test_dir OK(4/88) +**************************************** +Testing int operations... +checking a & b +checking a >= b +checking a ^ b +checking a >> b +checking a - b +checking a > b +checking a ** b +checking a < b +checking a != b +checking a + b +checking a <= b +checking divmod(a, b) +checking a << b +checking a * b +checking a / b +checking a == b +checking a | b +checking a % b +checking int(a) +checking - a +checking ~ a +checking float(a) +checking hex(a) +checking + a +checking long(a) +checking abs(a) +checking oct(a) +--> ints OK(5/88) +**************************************** +Testing long operations... +checking a & b +checking a >= b +checking a ^ b +checking a >> b +checking a - b +checking a > b +checking a ** b +checking a < b +checking a != b +checking a + b +checking a <= b +checking divmod(a, b) +checking a << b +checking a * b +checking a / b +checking a == b +checking a | b +checking a % b +checking int(a) +checking - a +checking ~ a +checking float(a) +checking hex(a) +checking + a +checking long(a) +checking abs(a) +checking oct(a) +--> longs OK(6/88) +**************************************** +Testing float operations... +checking a >= b +checking a - b +checking a > b +checking a ** b +checking a < b +checking a != b +checking a + b +checking a <= b +checking divmod(a, b) +checking a * b +checking a / b +checking a == b +checking a % b +checking int(a) +checking - a +checking float(a) +checking + a +checking long(a) +checking abs(a) +--> floats OK(7/88) +**************************************** +Testing complex operations... +checking a - b +checking a ** b +checking a != b +checking a + b +checking divmod(a, b) +checking a * b +checking a / b +checking a == b +checking a % b +checking - a +checking + a +checking abs(a) +--> complexes OK(8/88) +**************************************** +Testing Python subclass of dict... +pydict stress test ... +--> pydicts OK(9/88) +**************************************** +Testing Python subclass of list... +--> pylists OK(10/88) +**************************************** +Testing __metaclass__... +--> metaclass OK(11/88) +**************************************** +Testing Python subclass of module... +--> pymods OK(12/88) +**************************************** +Testing multiple inheritance... +--> multi OK(13/88) +**************************************** +Testing error messages for MRO disagreement... +--> mro_disagreement FAILURE(13/88) Message 'cycle among base classes: A < B < A', expected 'Cannot create a consistent method resolution\norder (MRO) for bases ' +**************************************** +Testing multiple inheritance special cases... +--> diamond OK(14/88) +**************************************** +Testing ex5 from C3 switch discussion... +--> ex5 OK(15/88) +**************************************** +Testing MRO monotonicity... +--> monotonicity OK(16/88) +**************************************** +Testing consistentcy with EPG... +--> consistency_with_epg OK(17/88) +**************************************** +Testing object class... +--> objects OK(18/88) +**************************************** +Testing __slots__... +--> slots FAILURE(18/88) ['foo bar'] slots not caught +**************************************** +Testing __dict__ and __weakref__ in __slots__... +--> slotspecials FAILURE(18/88) test failed +**************************************** +Testing class attribute propagation... +--> dynamics OK(19/88) +**************************************** +Testing errors... +--> errors FAILURE(19/88) inheritance from CFunction should be illegal +**************************************** +Testing class methods... +--> classmethods OK(20/88) +**************************************** +Testing static methods... +--> staticmethods OK(21/88) +**************************************** +Testing classic classes... +--> classic OK(22/88) +**************************************** +Testing computed attributes... +--> compattr OK(23/88) +**************************************** +Testing __new__ slot override... +--> newslot OK(24/88) +**************************************** +Testing mro() and overriding it... +--> altmro OK(25/88) +**************************************** +Testing operator overloading... +--> overloading OK(26/88) +**************************************** +Testing methods... +--> methods FAILURE(26/88) test failed +**************************************** +Testing special operators... +--> specials FAILURE(26/88) shouldn't allow .__cmp__(u'123', '123') +**************************************** +Testing weak references... +--> weakrefs FAILURE(26/88) No module named _weakref +**************************************** +Testing property... +--> properties FAILURE(26/88) expected TypeError from trying to set readonly '__doc__' attr on a property +**************************************** +Testing super... +--> supers OK(27/88) +**************************************** +Testing inheritance from basic types... +--> inherits FAILURE(27/88) test failed +**************************************** +Testing keyword args to basic type constructors ... +--> keywords OK(28/88) +**************************************** +--> restricted OK(29/88) +**************************************** +Testing a str subclass used as dict key .. +--> str_subclass_as_dict_key OK(30/88) +**************************************** +Testing classic comparisons... + (base = test.test_descr.classic) + (base = ) + (base = ) +--> classic_comparisons OK(31/88) +**************************************** +Testing rich comparisons... + (base = test.test_descr.classic) + (base = ) + (base = ) + (base = ) +--> rich_comparisons OK(32/88) +**************************************** +Testing coercions... +--> coercions OK(33/88) +**************************************** +Testing descriptor doc strings... +--> descrdoc FAILURE(33/88) None == 'True if the file is closed' +**************************************** +Testing __class__ assignment... +--> setclass OK(34/88) +**************************************** +Testing __dict__ assignment... +--> setdict OK(35/88) +**************************************** +Testing pickling and copying new-style classes and objects... +pickle text +a = x = C1(1, 2)<[42, 24]> +b = y = 42 +pickle binary +a = x = C1(1, 2)<[42, 24]> +b = y = 42 +cPickle text +a = x = C1(1, 2)<[42, 24]> +b = y = 42 +cPickle binary +a = x = C1(1, 2)<[42, 24]> +b = y = 42 +deepcopy +a = x = C1(1, 2)<[42, 24]> +b = y = 42 +--> pickles OK(36/88) +**************************************** +Testing copy.copy() and copy.deepcopy()... +--> copies OK(37/88) +**************************************** +Testing overrides of binary operations... +--> binopoverride OK(38/88) +**************************************** +Testing propagation of slot functions to subclasses... +--> subclasspropagation OK(39/88) +**************************************** +Testing that buffer interface is inherited ... +--> buffer_inherit OK(40/88) +**************************************** +Testing __str__ defined in subclass of str ... +--> str_of_str_subclass OK(41/88) +**************************************** +Testing keyword arguments to __init__, __call__... +--> kwdargs OK(42/88) +**************************************** +Testing __del__ hook... +--> delhook OK(43/88) +**************************************** +Testing hash of mutable subclasses... +--> hashinherit OK(44/88) +**************************************** +--> strops OK(45/88) +**************************************** +Testing deepcopy of recursive objects... +--> deepcopyrecursive OK(46/88) +**************************************** +Testing uninitialized module objects... +--> modules OK(47/88) +**************************************** +Testing dict-proxy iterkeys... +--> dictproxyiterkeys FAILURE(47/88) ['__dict__', '__doc__', '__module__', 'meth'] == ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'] +**************************************** +Testing dict-proxy itervalues... +--> dictproxyitervalues FAILURE(47/88) 4 == 5 +**************************************** +Testing dict-proxy iteritems... +--> dictproxyiteritems FAILURE(47/88) ['__dict__', '__doc__', '__module__', 'meth'] == ['__dict__', '__doc__', '__module__', '__weakref__', 'meth'] +**************************************** +Testing pickling of classes with __slots__ ... +--> pickleslots OK(48/88) +**************************************** +Testing __new__ returning something unexpected... +--> funnynew OK(49/88) +**************************************** +Testing for __imul__ problems... +--> imulbug OK(50/88) +**************************************** +Testing __doc__ descriptor... +--> docdescriptor OK(51/88) +**************************************** +Testing string exceptions ... +--> string_exceptions FAILURE(51/88) string subclass allowed as exception +**************************************** +Testing that copy.*copy() correctly uses __setstate__... +--> copy_setstate OK(52/88) +**************************************** +Testing cases with slices and overridden __getitem__ ... +--> slices OK(53/88) +**************************************** +Testing resurrection of new-style instance... +--> subtype_resurrection OK(54/88) +**************************************** +Testing slot trash... +--> slottrash OK(55/88) +**************************************** +--> slotmultipleinheritance FAILURE(55/88) type object 'C' has no attribute '__basicsize__' +**************************************** +Testing correct invocation of __rmul__... +--> testrmul OK(56/88) +**************************************** +Testing correct invocation of __ipow__... +--> testipow OK(57/88) +**************************************** +Testing mutable bases... +--> test_mutable_bases FAILURE(57/88) readonly attribute +**************************************** +Testing mutable bases with failing mro... +--> test_mutable_bases_with_failing_mro FAILURE(57/88) readonly attribute +**************************************** +Testing mutable bases catch mro conflict... +--> test_mutable_bases_catch_mro_conflict OK(58/88) +**************************************** +Testing mutable names... +--> mutable_names OK(59/88) +**************************************** +Testing correct dispatch of subclass overloading __r__... +--> subclass_right_op OK(60/88) +**************************************** +Testing type of __dict__ when __metaclass__ set... +--> dict_type_with_metaclass OK(61/88) +**************************************** +Testing __get__ method of METH_CLASS C methods... +--> meth_class_get FAILURE(61/88) shouldn't have allowed descr.__get__(None, None) +**************************************** +Testing proxy isinstance() and isclass()... +--> isinst_isclass OK(62/88) +**************************************** +Testing super() for a proxy object... +--> proxysuper OK(63/88) +**************************************** +Testing prohibition of Carlo Verre's hack... +--> carloverre OK(64/88) +**************************************** +Testing sys.stdout is changed in getattr... +--> filefault OK(65/88) +**************************************** +Testing vicious_descriptor_nonsense... +--> vicious_descriptor_nonsense OK(66/88) +**************************************** +--> test_init FAILURE(66/88) did not test __init__() for None return + +--===============0101701468== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +Loading grammar /Users/adim/var/pypy-dist/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0x14068> +fake-wrapping interp file ', mode 'w' at 0x140b0> +fake-wrapping interp file ', mode 'r' at 0x14020> +Traceback (application-level): + File "/Users/adim/var/pypy-dist/pypy/tool/pytest/regrverbose.py", line 12 in + indirect_test() + File "/Users/adim/var/pypy-dist/lib-python/modified-2.4.1/test/test_descr.py", line 4102 in test_main + raise TestFailed, "%d/%d" % (success, n) +TestFailed: 66/88 + +--===============0101701468==-- \ No newline at end of file Added: pypy/testresult/adim at eusebius.local/test_future.txt ============================================================================== --- (empty file) +++ pypy/testresult/adim at eusebius.local/test_future.txt Sat Oct 15 12:05:57 2005 @@ -0,0 +1,56 @@ +Content-Type: multipart/mixed; boundary="===============2133254534==" +MIME-Version: 1.0 +execution-time: 154.715417862 +exit status: 0 +fspath: /Users/adim/var/pypy-dist/lib-python/2.4.1/test/test_future.py +options: ['core'] +outcome: OK +platform: darwin +pypy-revision: 17668 +python-version-info: (2, 4, 1, 'final', 0) +startdate: Mon Sep 19 21:28:36 2005 +testreport-version: 1.1 +timeout: 3844.0 +userhost: adim at eusebius.local +_reprs: {'execution-time': 'float', 'python-version-info': 'tuple', + 'options': 'list', 'timeout': 'float', 'pypy-revision': 'int', + 'exit status': 'int'} + +--===============2133254534== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stdout" + +test_badfuture3 (test.test_future.FutureTest) ... ok +test_badfuture4 (test.test_future.FutureTest) ... ok +test_badfuture5 (test.test_future.FutureTest) ... ok +test_badfuture6 (test.test_future.FutureTest) ... ok +test_badfuture7 (test.test_future.FutureTest) ... ok +test_badfuture8 (test.test_future.FutureTest) ... ok +test_badfuture9 (test.test_future.FutureTest) ... ok +test_future1 (test.test_future.FutureTest) ... ok +test_future2 (test.test_future.FutureTest) ... ok +test_future3 (test.test_future.FutureTest) ... ok + +---------------------------------------------------------------------- +Ran 10 tests in 51.954s + +OK + +--===============2133254534== +Content-Type: text/plain; charset="us-ascii" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Content-Disposition: attachment; filename="stderr" + +Loading grammar /Users/adim/var/pypy-dist/pypy/interpreter/pyparser/data/Grammar2.4 +faking +faking +faking +faking +fake-wrapping interp file ', mode 'w' at 0x14068> +fake-wrapping interp file ', mode 'w' at 0x140b0> +fake-wrapping interp file ', mode 'r' at 0x14020> + +--===============2133254534==-- \ No newline at end of file From arigo at codespeak.net Sat Oct 15 12:55:57 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 12:55:57 +0200 (CEST) Subject: [pypy-svn] r18607 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051015105557.360E127B48@code1.codespeak.net> Author: arigo Date: Sat Oct 15 12:55:56 2005 New Revision: 18607 Modified: pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/test/test_database.py pypy/dist/pypy/translator/c/test/test_genc.py Log: Obscure dependency on the order of setup() calls in genc. Tweaked... Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Sat Oct 15 12:55:56 2005 @@ -19,6 +19,7 @@ self.translator = translator self.standalone = standalone self.structdefnodes = {} + self.pendingsetupnodes = [] self.containernodes = {} self.containerlist = [] self.completedcontainers = 0 @@ -51,7 +52,7 @@ else: raise Exception("don't know about %r" % (T,)) self.structdefnodes[key] = node - node.setup() + self.pendingsetupnodes.append(node) return node def gettype(self, T, varlength=1, who_asks=None, argnames=[]): @@ -129,36 +130,6 @@ 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 - return '' - if T.TO == PyObject: - return 'Py_XINCREF(%s);' % expr - else: - defnode = self.gettypedefnode(T.TO) - if defnode.gcheader is not None: - return 'if (%s) %s->%s++;' % (expr, expr, defnode.gcheader) - return '' - - def cdecrefstmt(self, expr, T): - if isinstance(T, Ptr) and T._needsgc(): - if T.TO == PyObject: - return 'Py_XDECREF(%s);' % expr - else: - defnode = self.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 '' -""" - def complete(self, show_progress=True): def dump(): lst = ['%s: %d' % keyvalue @@ -173,6 +144,11 @@ while True: if hasattr(self, 'pyobjmaker'): self.pyobjmaker.collect_initcode() + while self.pendingsetupnodes: + lst = self.pendingsetupnodes + self.pendingsetupnodes = [] + for nodedef in lst: + nodedef.setup() if i == len(self.containerlist): break node = self.containerlist[i] Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Sat Oct 15 12:55:56 2005 @@ -20,9 +20,18 @@ return False # gcheader already in the first field return True +class defaultproperty(object): + def __init__(self, fget): + self.fget = fget + def __get__(self, obj, cls=None): + if obj is None: + return self + else: + return self.fget(obj) + + class StructDefNode: gcheader = None - gcinfo = None def __init__(self, db, STRUCT, varlength=1): self.db = db @@ -76,17 +85,22 @@ else: typename = db.gettype(T, who_asks=self) self.fields.append((self.c_struct_field_name(name), typename)) + self.gcinfo # force it to be computed + def computegcinfo(self): + # let the gcpolicy do its own setup + self.gcinfo = None # unless overwritten below rtti = None + STRUCT = self.STRUCT if isinstance(STRUCT, GcStruct): try: rtti = getRuntimeTypeInfo(STRUCT) except ValueError: pass - - # let the gcpolicy do its own setup - if varlength == 1: + if self.varlength == 1: self.db.gcpolicy.struct_setup(self, rtti) + return self.gcinfo + gcinfo = defaultproperty(computegcinfo) def c_struct_field_name(self, name): return self.prefix + name @@ -151,7 +165,6 @@ class ArrayDefNode: gcheader = None - gcinfo = None def __init__(self, db, ARRAY, varlength=1): self.db = db @@ -180,12 +193,16 @@ def setup(self): db = self.db ARRAY = self.ARRAY - varlength = self.varlength self.itemtypename = db.gettype(ARRAY.OF, who_asks=self) + self.gcinfo # force it to be computed + def computegcinfo(self): # let the gcpolicy do its own setup - if varlength == 1: + self.gcinfo = None # unless overwritten below + if self.varlength == 1: self.db.gcpolicy.array_setup(self) + return self.gcinfo + gcinfo = defaultproperty(computegcinfo) def access_expr(self, baseexpr, index): return '%s.items[%d]' % (baseexpr, index) 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 Sat Oct 15 12:55:56 2005 @@ -49,6 +49,7 @@ s.x.y = 42 assert db.get(s).startswith('(&'+pfx) assert db.containernodes.keys() == [s._obj] + db.complete() assert len(db.structdefnodes) == 2 assert S in db.structdefnodes assert S.x in db.structdefnodes 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 Sat Oct 15 12:55:56 2005 @@ -202,6 +202,24 @@ res = f1(42) assert res == 42 +def test_recursive_struct_2(): + class L: + def __init__(self, target): + self.target = target + class RL(L): + pass + class SL(L): + pass + class B: + def __init__(self, exits): + self.exits = exits + def fn(i): + rl = RL(None) + b = B([rl]) + sl = SL(b) + f1 = compile(fn, [int]) + f1(42) + def test_infinite_float(): x = 1.0 while x != x / 2: From cfbolz at codespeak.net Sat Oct 15 12:58:26 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 15 Oct 2005 12:58:26 +0200 (CEST) Subject: [pypy-svn] r18608 - pypy/dist/pypy/rpython/l3interp/test Message-ID: <20051015105826.0028227B48@code1.codespeak.net> Author: cfbolz Date: Sat Oct 15 12:58:25 2005 New Revision: 18608 Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: remove view and actually run the compiled function Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sat Oct 15 12:58:25 2005 @@ -28,6 +28,6 @@ pol.allow_someobjects = False t.annotate([], policy=pol) t.specialize() - t.view() fn = t.ccompile() + assert fn() == 7 From hpk at codespeak.net Sat Oct 15 13:07:21 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 15 Oct 2005 13:07:21 +0200 (CEST) Subject: [pypy-svn] r18609 - pypy/dist/pypy/rpython/l3interp/test Message-ID: <20051015110721.EBF5D27B49@code1.codespeak.net> Author: hpk Date: Sat Oct 15 13:07:21 2005 New Revision: 18609 Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: (hpk,cfbolz) refactor and heading towards passing inputargs Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sat Oct 15 13:07:21 2005 @@ -4,6 +4,15 @@ from pypy.translator.translator import Translator from pypy.annotation import policy +def translate(func, inputargs): + t = Translator(func) + pol = policy.AnnotatorPolicy() + pol.allow_someobjects = False + t.annotate(inputargs, policy=pol) + t.specialize() + return t.ccompile() + +#---------------------------------------------------------------------- def eval_seven(): op = model.Operation(l3interp.LLFrame.op_int_add, 0, [-1, -2]) returnlink = model.ReturnLink(None, []) @@ -23,11 +32,21 @@ assert result == 7 def test_very_simple_translated(): + fn = translate(eval_seven, []) + assert fn() == 7 + +#---------------------------------------------------------------------- + +def Xtest_simple(): + result = eval_seven() + assert result == 7 + +def Xtest_very_simple_translated(): t = Translator(eval_seven) pol = policy.AnnotatorPolicy() pol.allow_someobjects = False t.annotate([], policy=pol) t.specialize() + t.view() fn = t.ccompile() - assert fn() == 7 From arigo at codespeak.net Sat Oct 15 13:07:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 13:07:30 +0200 (CEST) Subject: [pypy-svn] r18610 - in pypy/dist/pypy/interpreter: pyparser test Message-ID: <20051015110730.417E627B49@code1.codespeak.net> Author: arigo Date: Sat Oct 15 13:07:29 2005 New Revision: 18610 Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py pypy/dist/pypy/interpreter/test/test_compiler.py Log: Make the lexer generate "sensible" line numbers: continuation lines really increase the current line number. Modified: pypy/dist/pypy/interpreter/pyparser/pythonlexer.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/pythonlexer.py (original) +++ pypy/dist/pypy/interpreter/pyparser/pythonlexer.py Sat Oct 15 13:07:29 2005 @@ -67,7 +67,12 @@ This is a rewrite of pypy.module.parser.pytokenize.generate_tokens since the original function is not RPYTHON (uses yield) It was also slightly modified to generate Token instances instead - of the original 5-tuples + of the original 5-tuples -- it's now a 4-tuple of + + * the Token instance + * the whole line as a string + * the line number (the real one, counting continuation lines) + * the position on the line of the end of the token. Original docstring :: @@ -189,7 +194,7 @@ raise TokenError("Unknown character", line, (lnum, start), token_list) - spos, epos, pos = (lnum, start), (lnum, end), end + pos = end token, initial = line[start:end], line[start] if initial in numchars or \ (initial == '.' and token != '.'): # ordinary number @@ -244,7 +249,7 @@ last_comment = '' elif initial == '\\': # continued stmt continued = 1 - lnum -= 1 + # lnum -= 1 disabled: count continuation lines separately else: if initial in '([{': parenlev = parenlev + 1 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 Sat Oct 15 13:07:29 2005 @@ -336,7 +336,7 @@ w_fline = space.getitem(w_d, space.wrap('fline')) w_gline = space.getitem(w_d, space.wrap('gline')) assert space.int_w(w_fline) == 2 - #IN-PROGRESS assert space.int_w(w_gline) == 6 + assert space.int_w(w_gline) == 6 class TestECCompiler(BaseTestCompiler): def setup_method(self, method): From hpk at codespeak.net Sat Oct 15 13:28:28 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 15 Oct 2005 13:28:28 +0200 (CEST) Subject: [pypy-svn] r18613 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051015112828.6AA8A27B48@code1.codespeak.net> Author: hpk Date: Sat Oct 15 13:28:28 2005 New Revision: 18613 Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py pypy/dist/pypy/rpython/l3interp/model.py pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: (hpk,cfbolz) implemented passing of arguments (ints only actually) Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/l3interp.py Sat Oct 15 13:28:28 2005 @@ -17,10 +17,9 @@ self.graph = graph self.int_vars = [0] * graph.max_num_ints - def eval(self, args): - assert len(args) == 0, "not implemented, XXX" + def eval(self, int_values): link = self.graph.startlink -# self.fill_input_arg(... + self.copy_startlink_vars(link, int_values) while type(link) is model.Link: link = self.eval_block(link.target) self.copy_link_vars(link) @@ -35,9 +34,16 @@ return link return block.exits[0] + def copy_startlink_vars(self, link, int_values): + if link.move_int_registers is None: + return + for i in range(0, len(link.move_int_registers), 2): + source = link.move_int_registers[i] + target = link.move_int_registers[i + 1] + self.set_int(target, int_values[source]) def copy_link_vars(self, link): - if not len(link.move_int_registers): + if link.move_int_registers is None: return for i in range(0, len(link.move_int_registers), 2): source = link.move_int_registers[i] Modified: pypy/dist/pypy/rpython/l3interp/model.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/model.py (original) +++ pypy/dist/pypy/rpython/l3interp/model.py Sat Oct 15 13:28:28 2005 @@ -95,12 +95,11 @@ self.result = result # resulting variable class Link(object): - def __init__(self, target, args, exitcase=None): + def __init__(self, target, exitcase=None): self.target = target # target is a Block - self.intargs = args # args is a list of ints, same meaning as Operation.args self.exitcase = exitcase # NULL for non-exceptional case # address of exception class else - self.move_int_registers = [] + self.move_int_registers = None class ReturnLink(Link): pass Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sat Oct 15 13:28:28 2005 @@ -36,17 +36,25 @@ assert fn() == 7 #---------------------------------------------------------------------- +def eval_eight(number): + op = model.Operation(l3interp.LLFrame.op_int_add, 1, [0, -1]) + returnlink = model.ReturnLink(target=None) + returnlink.move_int_registers = [1, 0] + block = model.Block([], model.ONE_EXIT, [returnlink]) + block.operations.append(op) + startlink = model.Link(target=block) + startlink.move_int_registers = [0, 0] + graph = model.Graph("testgraph", startlink) + graph.set_constants_int([4]) + g = model.Globals() + g.graphs = [graph] + interp = l3interp.LLInterpreter() + return interp.eval_graph_int(graph, [number]) -def Xtest_simple(): - result = eval_seven() - assert result == 7 - -def Xtest_very_simple_translated(): - t = Translator(eval_seven) - pol = policy.AnnotatorPolicy() - pol.allow_someobjects = False - t.annotate([], policy=pol) - t.specialize() - t.view() - fn = t.ccompile() +def test_simple(): + result = eval_eight(4) + assert result == 8 +def test_simple_translated(): + fn = translate(eval_eight, [int]) + assert fn(4) == 8 From ludal at codespeak.net Sat Oct 15 13:29:42 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 15 Oct 2005 13:29:42 +0200 (CEST) Subject: [pypy-svn] r18614 - pypy/dist/pypy/module/Numeric Message-ID: <20051015112942.CDA8C27B48@code1.codespeak.net> Author: ludal Date: Sat Oct 15 13:29:41 2005 New Revision: 18614 Modified: pypy/dist/pypy/module/Numeric/interp_numeric.py Log: * fix get_storage_size * implement wrapping classes for multi_index representation * implements slice extraction Modified: pypy/dist/pypy/module/Numeric/interp_numeric.py ============================================================================== --- pypy/dist/pypy/module/Numeric/interp_numeric.py (original) +++ pypy/dist/pypy/module/Numeric/interp_numeric.py Sat Oct 15 13:29:41 2005 @@ -7,30 +7,83 @@ from pypy.interpreter.gateway import interp2app, ObjSpace, W_Root +class Index(object): + """Base index class representing either an integer, a slice, an ellipsis""" + +class IntIndex(Index): + def __init__(self, intval ): + self.index = intval + +class SliceIndex(Index): + def __init__(self, sliceval ): + self.slice = sliceval + + def indices(self, dim): + """Returns the size of the slice given the dimension of the array + it applies to""" + # probably not RPython + return self.slice.indices( dim ) + + +class EllipsisIndex(Index): + def __init__(self): + pass + def get_storage_size( dims ): n = 1 for d in dims: n *= d assert d>0 - return d + return n + +def is_integer( space, w_obj ): + return space.is_true(space.isinstance( w_obj, space.w_int ) ) + +def convert_index_type( space, w_obj ): + if space.is_true(space.isinstance( w_obj, space.w_int ) ): + return [ IntIndex( space.int_w(w_obj) ) ], False, False + if not space.is_true(space.isinstance( w_obj, space.w_tuple )): + raise OperationError(space.w_IndexError, + space.wrap("index must be either an int or a sequence")) + multi_index = [] + has_slice = False + has_ellipsis = False + for w_idx in space.unpackiterable( w_obj ): + if space.is_true(space.isinstance( w_idx, space.w_int )): + multi_index.append( IntIndex( space.int_w( w_idx ) ) ) + elif space.is_true(space.isinstance( w_idx, space.w_slice )): + multi_index.append( SliceIndex( space.unwrap( w_idx ) ) ) + has_slice = True + elif space.is_w( w_idx, space.w_Ellipsis ): + multi_index.append( EllipsisIndex() ) + has_ellipsis = True + else: + raise OperationError(space.w_IndexError, + space.wrap("each subindex must be either a " + "slice, an integer, Ellipsis, or" + " NewAxis")) + return multi_index, has_slice, has_ellipsis + class W_Array(Wrappable): - def __init__(self, space, dims ): + def __init__(self, space, dims, strides=None ): self.space = space assert isinstance(dims, list) self.dims = dims self.strides = [1] - self.base_object = None - self.base_offset = 0 # needed later for offseting into a shared storage - stride = 1 - for n in self.dims[:-1]: - stride *= n - self.strides.append( stride ) - self.strides.reverse() + self.base_offset = 0 + if strides is None: + stride = 1 + for n in self.dims[:-1]: + stride *= n + self.strides.append( stride ) + self.strides.reverse() + else: + self.strides=strides - def check_space_true(self, space, w_index): + def check_scalar_index(self, space, w_index): if not space.is_true(space.isinstance( w_index, space.w_int )): raise NotImplementedError idx = space.unwrap( w_index ) @@ -38,22 +91,44 @@ return idx def descr___getitem__( self, space, w_index ): - return self.get_single_item( space, [ self.check_space_true( space, w_index)]) + multi_idx, has_slice, has_ellipsis = convert_index_type( space, w_index ) + if not has_slice and not has_ellipsis and len(multi_idx)==len(self.dims): + idx_tuple = [] + for idx in multi_idx: + assert isinstance(idx, IntIndex) + idx_tuple.append(idx.index) + return self.get_single_item( space, idx_tuple ) + if has_ellipsis: + # replace ellipsis with slice objects according to array dimensions + # TODO + pass + return self.get_slice( space, multi_idx ) def descr___setitem__( self, space, w_index, w_value ): - return self.set_single_item( space, [ self.check_space_true( space, w_index) ], w_value ) + multi_idx, has_slice, has_ellipsis = convert_index_type( space, w_index ) + if not has_slice and not has_ellipsis and len(multi_idx)==len(self.dims): + idx_tuple = [] + for idx in multi_idx: + assert isinstance(idx, IntIndex) + idx_tuple.append(idx.index) + return self.set_single_item( space, idx_tuple, w_value ) + if len(multi_idx)len(self.dims): # TODO raise OperationError raise RuntimeError - idx = 0 + idx = self.base_offset for i in range(len(idx_tuple)): idx += self.strides[i]*idx_tuple[i] return idx @@ -61,23 +136,24 @@ class W_Array_Float(W_Array): - def __init__(self, space, dims, storage=None ): - W_Array.__init__(self, space, dims ) - storage_size = get_storage_size(dims) + def __init__(self, space, dims, strides=None, storage=None ): + W_Array.__init__(self, space, dims, strides ) self.storage = [] if storage is not None: assert isinstance(storage, list) # TODO return proper exception here - assert len(storage)==storage_size + # assert len(storage)==storage_size ### can't check that because of slicing assert isinstance(storage[0], float) self.storage = storage else: + storage_size = get_storage_size(dims) self.storage = [0.0]*storage_size def get_single_item( self, space, idx_tuple ): if len(idx_tuple)!=len(self.dims): # TODO raise OperationError or remove this and make it a pre-condition raise RuntimeError + idx = self.get_array_offset( idx_tuple ) return space.wrap( self.storage[idx] ) @@ -86,18 +162,36 @@ value = space.float_w( w_value ) self.storage[idx] = value + def get_slice( self, space, multi_idx ): + # compute dim of extracted array + dims = [] + strides = [] + last_stride = 1 + offset = self.base_offset + for i in range(len(multi_idx)): + idx = multi_idx[i] + if isinstance( idx, SliceIndex): + start, stop, step = idx.indices( self.dims[i] ) + dim = (stop-start)//step + stride = self.strides[i]*step + dims.append( dim ) + strides.append( step ) + elif isinstance( idx, IntIndex ): + offset+= idx.index*self.strides[i] + array = W_Array_Float( space, dims, strides, self.storage ) + return space.wrap(array) + + descr___getitem__ = interp2app( W_Array.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) descr___setitem__ = interp2app( W_Array.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) -#get_shape = GetProperty( W_Array_Float. - -W_Array.typedef = TypeDef("W_Array", +W_Array.typedef = TypeDef("array", shape = GetSetProperty( W_Array.fget_shape, cls=W_Array), __getitem__ = descr___getitem__, __setitem__ = descr___setitem__, ) -W_Array_Float.typedef = TypeDef("W_Array_Float", W_Array.typedef, +W_Array_Float.typedef = TypeDef("array_float", W_Array.typedef, ) def w_zeros( space, w_dim_tuple, type_str ): @@ -111,6 +205,8 @@ w_zeros.unwrap_spec = [ ObjSpace, W_Root, str ] + + """ """ class W_NumericArray(Wrappable): From bea at codespeak.net Sat Oct 15 13:30:07 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sat, 15 Oct 2005 13:30:07 +0200 (CEST) Subject: [pypy-svn] r18615 - pypy/extradoc/planning Message-ID: <20051015113007.4558227B4B@code1.codespeak.net> Author: bea Date: Sat Oct 15 13:29:14 2005 New Revision: 18615 Added: pypy/extradoc/planning/phase2_projectactivities.txt Log: preliminary draft pl,an for the meeting 15/10 2005 in Paris sprint, updated with dates for conferences and sprint planning data, and also eu roadmaps etc Also changed name of file Added: pypy/extradoc/planning/phase2_projectactivities.txt ============================================================================== --- (empty file) +++ pypy/extradoc/planning/phase2_projectactivities.txt Sat Oct 15 13:29:14 2005 @@ -0,0 +1,190 @@ + +Rough preparation draft for saturday-afternoon 20051015 meeting Paris +------------------------------------------------------------- + +sprints & conferences +------------------------- + + + *5-11th December (?): + Meeting in Sweden? Change Maker?/G?tabergsgatan? + + A sprint around bruxelles might make sense, + holger is checking with bruxelles and Louvain-la-neuve + (near bruxelles) people for a sprint beginning of + december. Bea is checking with Mallorca/Barcelona + regarding the same time frame. Nothing definitive + yet, alas! + + *23-29th January: CS Dep. of the Palma de Mallorca University/CS Dep. of the Barcelona University + Bea check dates, Bruxelles/Louvain-la-neuve, Holger check dates), + + *27-29th February: PyCon (24-26 Feb, 2006 Dallas, Texas, Presperint?, Holger) + + *April Japan: (1) April 23 to April 29, (2) April 30 to May 5, contact: Yutaka Niibe, + National Institute of AIST, Japan (FSIJ) Akihabara, Tokyo (Bea) + + *6-9th (?) July: Europython Cern (3-5th July (?) Swizerland, Michael/Holger?) + + *21-27th August: University of Limerick/Ireland (Bea) + + *2-8th October: ? + + Other possibilities: Romania, Switzerland (Leysin,Bern), Uganda (Nkozi) + +- Conference/y?talks planning: + + HALF-FIXED:8th December 2005 Calibre/agile development workshop in + Bruxelles, Bea, Holger, Alastair attending (or maybe + just two persons). Bea coordinates (Alastair?). + + FIXED:27th October2005 PMI Chapter Sweden, methodology/PyPy talk in Link?ping (Bea) + + HALF-FIXED: CCC 27th-30th December Berlin (pypy technical talk accepted, + non-technical talk pending, may be unlikely, holger is keeping + contact) + + HALF-FIXED: 17th January 2006 (16th and or 18th): IONA/University College Dublin (UCD)+second university, + contact Joe Kiniry UCD, Sean Baker/Niall Donelly IONA) + Holger/Bea do talks about PyPy - methodology and tehnical aspects + + FIXED: Solution Linux 2006 (31st Januray-2nd Feb): + Logilab will present PyPy in the "free software models" track. + + OPEN: PyCon, 24th-26th Feburary: Holger wants to submit one or two proposals + and go there, also doing a py lib and/or pypy-sprint. Bea wants to submit methodology talk. + Note that sprints are scheduled after the conf. + DEADLINE: 30th October (in two weeks!) + + OPEN: 3 of March 2006 Sk?vde Sweden, CALIBRE Workshop on Distributed Development, + Open Source & Industry- Opportunities, Suspicions, & Strategies (Bea) + + OPEN: XP 2006, 17-22th June 2006 Oulu Finland + Submission date: 1 march 2006 (methodology talk/workshop?/Bea) + + OPEN: 3-5th July 2006 Europython Cern Switzerland + Submission date: ? + + OPEN: OOPSLA 2006 (no date?) + Submission date: ? + + OPEN: Calibre conferences + + OPEN: Agile Alliance conferences? + Submission date: ? + + OPEN: ACCU? + Submission date:? + +pypy technical task planning +---------------------------------- + +Identify tasks to be done in between sprints, start with +see paris-2005-possible-tasks.txt: + +- full compiler/parser integration + +- pypy-sync meetings should constantly track/amend/modify those + technical tasks and in general focus on technical issues + NOTE though: pypy-sync cannot focus too much on EU requirements + because it's a more open/community forum. + +EU-related Workpackage planning planning phase 2 +------------------------------------------------- + +- WP09 and WP10 done and coordinated by logilab/dfki + people. they should update the rest of us regarding + planning and also communicate regarding + possible related sprint topics. + +- WP02 dev infrastructure is merlinux responsibility, + should also suggest sprint topics (considering e.g. + a py lib sprint at PyCon ...) + +- other WPs in phase 2 are probably more generally in + common responsibility (like WP04/WP05) with the lead + partner taking special responsibility (towards the EU): + + - WP03 (HHU) synchronisation CPython + - WP06 (HHU) core optimisations + - WP07 (tismerysoft) translator optimisations + - WP08 (Strakt) dynamic optimisations + - WP14 (Changemaker) dissemination/project representation + + open: + + - WP05: left over work for Impara (when they get accepted)? + + +EU-related report planning +------------------------------------------------- + +People (primary) and co-reviewers (secondary) and completion dates: +(lead partner coordinating, technical board evaluating overall consistency) + +DO1.1 Create QA plan for the project +Primary/Secondary: Bea/Holger +Completion date: 16th Oct 2005 + +D04.1 Partial Python Impl: +Primary/Secondary:Jacob/? +Completion date: + +D04.2 Complete Python Impl: +Primary/Secondary:Jacob? +Completion date: + +D04.3 Parser report: +Primary/Secondary:Jacob? +Completion date: + +D04.4 Release PyPy-research-tool: +Primary/Secondary:Jacob? +Completion date: + +D05.1 Publish on translating a very-high-level description: +Primary/Secondary:Armin/ +Completion date: + +D05.2 A compiled, self-contained version of PyPy: +Primary/Secondary:Armin/ +Completion date: + +D05.3 Publish on implementation with translation aspects: +Primary/Secondary:Armin/ +Completion date: + +D05.4 Publish on encapsulating low level language aspects: +Primary/Secondary:Armin +Completion date: + +D14.1 Report about Milestone/Phase 1: +Primary/Secondary:Bea/Stephan +Completion date:21th October 2005 + +Review planning: + +Roadmap: + +*31th October 2005: all partners check completeness of timesheets Dec 2004-Oct 2005 +(Stephan wp1, Jacob wp3,4,5, Bea wp14, all partners) + +*5th December 2005: all partners submit timesheets for November 2005 +(Stephan wp1, Jacob wp3,4,5, Bea wp14, all partners) + +*9th December 2005: Periodic management/activity reports updated with all data but costs +(Jacob//Bea) + +*15th December 205: submit reports to EC/reviewers +(Stephan) + +*16th December 2005: all partners submit FORM C:s to DFKI (or communicate a new + completion date for this!) +(Stephan, all partners) + +*10th January 2006: review in Brussels +(Stephan) + +*15th of January 2006: submit FORM C:s to EC/PO and possible updated periodic management/ +activity reports +(Stephan//Jacob,Bea \ No newline at end of file From boria at codespeak.net Sat Oct 15 13:32:14 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Sat, 15 Oct 2005 13:32:14 +0200 (CEST) Subject: [pypy-svn] r18616 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051015113214.CC5CA27B48@code1.codespeak.net> Author: boria Date: Sat Oct 15 13:32:12 2005 New Revision: 18616 Added: pypy/dist/pypy/rpython/ootypesystem/rclass.py (contents, props changed) pypy/dist/pypy/rpython/ootypesystem/rpbc.py (contents, props changed) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/typesystem.py Log: (pedronis, boria) * Further work on ootypesystem. * Initial support for classes. * test_simple_empty_base() in ootypesystem/test/test_ooclean.py now passes. Added: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sat Oct 15 13:32:12 2005 @@ -0,0 +1,40 @@ +from pypy.rpython.rmodel import inputconst +from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr +from pypy.rpython.ootypesystem import ootype + +CLASSTYPE = ootype.Class + +class ClassRepr(AbstractClassRepr): + def __init__(self, rtyper, classdef): + AbstractClassRepr.__init__(self, rtyper, classdef) + + self.lowleveltype = ootype.Class + + def _setup_repr(self): + # FIXME to be completed + pass + + def convert_const(self): + # FIXME + pass + +class InstanceRepr(AbstractInstanceRepr): + def __init__(self, rtyper, classdef, does_need_gc=True): + AbstractInstanceRepr.__init__(self, rtyper, classdef) + + self.lowleveltype = ootype.Instance(classdef.cls.__name__, None, {}, {}) + self.prebuiltinstances = {} # { id(x): (x, _ptr) } + + def _setup_repr(self): + # FIXME fields, methods + pass + + def convert_const(self): + # FIXME + pass + + def new_instance(self, llops): + """Build a new instance, without calling __init__.""" + + return llops.genop("new", + [inputconst(ootype.Void, self.lowleveltype)], self.lowleveltype) Added: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Sat Oct 15 13:32:12 2005 @@ -0,0 +1,12 @@ +from pypy.rpython.rpbc import AbstractClassesPBCRepr +from pypy.rpython.rclass import rtype_new_instance +from pypy.rpython.ootypesystem import ootype + +class ClassesPBCRepr(AbstractClassesPBCRepr): + def rtype_simple_call(self, hop): + if self.lowleveltype is not ootype.Void: + raise NotImplementedError() + + klass = self.s_pbc.const + v_instance = rtype_new_instance(hop.rtyper, klass, hop.llops) + return v_instance Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sat Oct 15 13:32:12 2005 @@ -38,7 +38,7 @@ class EmptyBase(object): pass -def inprogress_test_simple_empty_base(): +def test_simple_empty_base(): def dummyfn(): x = EmptyBase() return x Modified: pypy/dist/pypy/rpython/typesystem.py ============================================================================== --- pypy/dist/pypy/rpython/typesystem.py (original) +++ pypy/dist/pypy/rpython/typesystem.py Sat Oct 15 13:32:12 2005 @@ -9,6 +9,27 @@ class TypeSystem(object): __metaclass__ = extendabletype + def __getattr__(self, name): + """Lazy import to avoid circular dependencies.""" + def load(modname): + try: + return __import__("pypy.rpython.%s.%s" % (self.name, modname), + None, None, ['__doc__']) + except ImportError: + return None + if name in ('rclass', 'rpbc'): + mod = load(name) + if mod is not None: + setattr(self, name, mod) + return mod + elif name == "BUILTIN_TYPER": + rbuiltin = load('rbuiltin') + if rbuiltin is not None: + self.BUILTIN_TYPER = rbuiltin.BUILTIN_TYPER + return self.BUILTIN_TYPER + + raise AttributeError(name) + def deref(self, obj): """Dereference `obj' to concrete object.""" raise NotImplementedError() @@ -38,29 +59,9 @@ raise NotImplementedError() class LowLevelTypeSystem(TypeSystem): + name = "lltypesystem" callable_trait = (lltype.FuncType, lltype.functionptr) - def __getattr__(self, name): - """Lazy import to avoid circular dependencies.""" - # FIXME refactor into TypeSystem - if name == "rclass": - from pypy.rpython.lltypesystem import rclass - self.rclass = rclass - - return rclass - elif name == "rpbc": - from pypy.rpython.lltypesystem import rpbc - self.rpbc = rpbc - - return rpbc - elif name == "BUILTIN_TYPER": - from pypy.rpython.lltypesystem import rbuiltin - self.BUILTIN_TYPER = rbuiltin.BUILTIN_TYPER - - return self.BUILTIN_TYPER - else: - raise AttributeError(name) - def deref(self, obj): assert isinstance(lltype.typeOf(obj), lltype.Ptr) return obj._obj @@ -74,6 +75,7 @@ return getattr(v, 'concretetype', lltype.Ptr(lltype.PyObject)) class ObjectOrientedTypeSystem(TypeSystem): + name = "ootypesystem" callable_trait = (ootype.StaticMethod, ootype.static_meth) # FIXME rclass From ludal at codespeak.net Sat Oct 15 13:33:10 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 15 Oct 2005 13:33:10 +0200 (CEST) Subject: [pypy-svn] r18617 - pypy/dist/pypy/module/Numeric Message-ID: <20051015113310.9E09227B48@code1.codespeak.net> Author: ludal Date: Sat Oct 15 13:33:09 2005 New Revision: 18617 Added: pypy/dist/pypy/module/Numeric/app_numeric.py - copied unchanged from r18606, pypy/dist/pypy/module/Numeric/test_numeric.py Removed: pypy/dist/pypy/module/Numeric/test_numeric.py Log: * renamed test_numeric From aft at codespeak.net Sat Oct 15 13:40:31 2005 From: aft at codespeak.net (aft at codespeak.net) Date: Sat, 15 Oct 2005 13:40:31 +0200 (CEST) Subject: [pypy-svn] r18619 - pypy/dist/pypy/module/Numeric Message-ID: <20051015114031.9C79427B49@code1.codespeak.net> Author: aft Date: Sat Oct 15 13:40:28 2005 New Revision: 18619 Modified: pypy/dist/pypy/module/Numeric/__init__.py pypy/dist/pypy/module/Numeric/app_numeric.py pypy/dist/pypy/module/Numeric/interp_numeric.py Log: Merging... Modified: pypy/dist/pypy/module/Numeric/__init__.py ============================================================================== --- pypy/dist/pypy/module/Numeric/__init__.py (original) +++ pypy/dist/pypy/module/Numeric/__init__.py Sat Oct 15 13:40:28 2005 @@ -3,7 +3,7 @@ class Module(MixedModule): """An RPython reimplementation of the Numeric module """ - + appleveldefs = { } @@ -12,10 +12,11 @@ 'Int' : "space.wrap('l')", # 'array' : 'interp_numeric.w_array', 'zeros' : 'interp_numeric.w_zeros', - 'nzeros' : 'interp_numeric.w_nzeros', - 'array' : 'interp_numeric.w_array', + 'array' : 'interp_numeric.array', + 'TOWER_TYPES' : 'space.wrap(interp_numeric.TOWER_TYPES)', + 'TOWER_TYPES_VALUES' :'space.wrap(interp_numeric.TOWER_TYPES_VALUES)' } - + ## 'CODESIZE': 'space.wrap(interp_sre.CODESIZE)', ## 'MAGIC': 'space.wrap(interp_sre.MAGIC)', ## 'copyright': 'space.wrap(interp_sre.copyright)', Modified: pypy/dist/pypy/module/Numeric/app_numeric.py ============================================================================== --- pypy/dist/pypy/module/Numeric/app_numeric.py (original) +++ pypy/dist/pypy/module/Numeric/app_numeric.py Sat Oct 15 13:40:28 2005 @@ -1,34 +1,11 @@ -from Numeric import zeros,nzeros,array -from Numeric import Float +from Numeric import zeros,array +from Numeric import Float,TOWER_TYPES,TOWER_TYPES_VALUES -class TestArray: - def test(self): - a = zeros( (3,2), Float ) - assert (3,2) == a.shape - b = zeros( (8,), Float ) - assert 0.==b[1] - b[1]= 1. - assert 1.==b[1] - - def testZeros(self): - pass - -TestArray().test() -TestArray().testZeros() -#### Original test above. - -a=nzeros((2,7),Float) - -assert (2,7)== a.shape -b=nzeros((10,),Float) -assert 0.==b[2] -b[3]=555 -assert b[3]==555 def assertRaises(block,exception=Exception,shout='This should raise an exception'): try: @@ -38,8 +15,32 @@ else: assert False,shout +""" +PyPy issues : >>>> 1=1 produces syntax error, but in script, takes AGES to eventually do this. +this is due to the size of the traceback which is generated in the script. + +""" +#first we check the really simple, empty or minimal arrays +assert (0,)==array(()).shape +assert ()==array((1)).shape +assert array(()).isArray() and array((1)).isArray() + +#next we check the typecodes on these small examples +assert 'l'==array(()).typecode() +assert 'l'==array((1)).typecode() +assert 'd'==array((1.0)).typecode() + +#we are not supporting complex numbers or any other objects yet +assertRaises(lambda :array((1j)),ValueError) +assertRaises(lambda :array((1j,)),ValueError) +assertRaises(lambda :array(('a')),ValueError) + +#now check accessing of values on empty array, and a scalar +#assertRaises(lambda :array(())[0],IndexError + + + + + -assertRaises(lambda :array(()),exception=ValueError) #this should fail -a=array([1]) -#assert a[0]==1 last test broken... Modified: pypy/dist/pypy/module/Numeric/interp_numeric.py ============================================================================== --- pypy/dist/pypy/module/Numeric/interp_numeric.py (original) +++ pypy/dist/pypy/module/Numeric/interp_numeric.py Sat Oct 15 13:40:28 2005 @@ -153,7 +153,7 @@ if len(idx_tuple)!=len(self.dims): # TODO raise OperationError or remove this and make it a pre-condition raise RuntimeError - + idx = self.get_array_offset( idx_tuple ) return space.wrap( self.storage[idx] ) @@ -180,7 +180,7 @@ offset+= idx.index*self.strides[i] array = W_Array_Float( space, dims, strides, self.storage ) return space.wrap(array) - + descr___getitem__ = interp2app( W_Array.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) descr___setitem__ = interp2app( W_Array.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) @@ -211,18 +211,10 @@ """ class W_NumericArray(Wrappable): - def __init__(self, space, dims ): + def __init__(self, space, dims ,value=None ): self.space = space - assert isinstance(dims, list) self.dims = dims - self.strides = [1] - self.base_object = None - self.base_offset = 0 # needed later for offseting into a shared storage - stride = 1 - for n in self.dims[:-1]: - stride *= n - self.strides.append( stride ) - self.strides.reverse() + self.value= value def check_space_true(self, space, w_index): if not space.is_true(space.isinstance( w_index, space.w_int )): @@ -231,6 +223,15 @@ assert isinstance( idx, int ) return idx + def isArray(self,space): + return self.space.wrap(True) + + def typecode(self,space): + code='l' + if isinstance(self.value,float): + code='d' + return self.space.wrap(code) + def descr___getitem__( self, space, w_index ): return self.get_single_item( space, [ self.check_space_true( space, w_index)]) @@ -252,22 +253,6 @@ idx += self.strides[i]*idx_tuple[i] return idx - -class W_NumericArray_Float(W_NumericArray): - - def __init__(self, space, dims, storage=None ): - W_NumericArray.__init__(self, space, dims ) - storage_size = get_storage_size(dims) - self.storage = [] - if storage is not None: - assert isinstance(storage, list) - # TODO return proper exception here - assert len(storage)==storage_size - assert isinstance(storage[0], float) - self.storage = storage - else: - self.storage = [0.0]*storage_size - def get_single_item( self, space, idx_tuple ): if len(idx_tuple)!=len(self.dims): # TODO raise OperationError or remove this and make it a pre-condition @@ -280,32 +265,44 @@ value = space.float_w( w_value ) self.storage[idx] = value + + + descr___getitem__ = interp2app( W_NumericArray.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) descr___setitem__ = interp2app( W_NumericArray.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) +isArray = interp2app( W_NumericArray.isArray, unwrap_spec=['self', ObjSpace ] ) +typecode = interp2app( W_NumericArray.typecode, unwrap_spec=['self', ObjSpace ] ) + + W_NumericArray.typedef = TypeDef("W_NumericArray", shape = GetSetProperty( W_NumericArray.fget_shape, cls=W_NumericArray), + isArray = isArray, + typecode= typecode, __getitem__ = descr___getitem__, __setitem__ = descr___setitem__, ) -W_NumericArray_Float.typedef = TypeDef("W_NumericArray_Float", W_NumericArray.typedef, - ) - -def w_nzeros( space, w_dim_tuple, type_str ): - dims = [] - for w_int in space.unpackiterable(w_dim_tuple): - dims.append( space.unwrap( w_int ) ) - if type_str == 'd': - return space.wrap(W_NumericArray_Float( space, dims )) - raise OperationError( space.w_ValueError, space.wrap('Unknown type code') ) +TOWER_TYPES_VALUES=[(int,1),(float,1.0),(complex,2.0+3j)] #we will work with these types to start with +TOWER_TYPES_VALUES=TOWER_TYPES_VALUES[0:2] #cannot unpack complex values yet at interp level. -w_nzeros.unwrap_spec = [ ObjSpace, W_Root, str ] +TOWER_TYPES=[typ for typ,val in TOWER_TYPES_VALUES] +def OpError(space,w_arg): + raise OperationError( space.w_ValueError,space.wrap('Cannot unwrap this <%s>'%str(w_arg))) -def w_array( space, w_dim_tuple): - raise OperationError( space.w_ValueError, space.wrap('Cannot create void array')) +def array( space, w_arg): + try: + arg=space.unwrap( w_arg) + except: + OpError(space,w_arg) + if arg in ((),[]): + return W_NumericArray(space,(0,)) + if type(arg) not in (int,float): + OpError(space,w_arg) + else: + return W_NumericArray(space,(),value=arg) -w_array.unwrap_spec = [ ObjSpace, W_Root ] +array.unwrap_spec = [ ObjSpace, W_Root ] From arigo at codespeak.net Sat Oct 15 14:55:45 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 14:55:45 +0200 (CEST) Subject: [pypy-svn] r18624 - in pypy/dist/pypy: annotation module/__builtin__ rpython translator/c/src Message-ID: <20051015125545.8533127B48@code1.codespeak.net> Author: arigo Date: Sat Oct 15 14:55:43 2005 New Revision: 18624 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/module/__builtin__/operation.py pypy/dist/pypy/rpython/rfloat.py pypy/dist/pypy/translator/c/src/float.h Log: removed support for '%' between floats in RPython. This was broken in genc (didn't check the signs correctly) and should just be done by calling math.fmod(), which is explicitely not guaranteed to do the right thing with signs. Fixed the only place in the interpreter that uses it and that was causing a buggy round() in pypy-c. Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Sat Oct 15 14:55:43 2005 @@ -337,7 +337,7 @@ def union((flt1, flt2)): return SomeFloat() - add = sub = mul = div = truediv = floordiv = mod = union + add = sub = mul = div = truediv = union def pow((flt1, flt2), obj3): return SomeFloat() Modified: pypy/dist/pypy/module/__builtin__/operation.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/operation.py (original) +++ pypy/dist/pypy/module/__builtin__/operation.py Sat Oct 15 14:55:43 2005 @@ -71,13 +71,8 @@ # ____________________________________________________________ -def _floor(f): - return f - (f % 1.0) - -def _ceil(f): - if f - (f % 1.0) == f: - return f - return f + 1.0 - (f % 1.0) +from math import floor as _floor +from math import ceil as _ceil def round(space, number, ndigits=0): """round(number[, ndigits]) -> floating point number Modified: pypy/dist/pypy/rpython/rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/rfloat.py (original) +++ pypy/dist/pypy/rpython/rfloat.py Sat Oct 15 14:55:43 2005 @@ -48,11 +48,6 @@ rtype_truediv = rtype_div rtype_inplace_truediv = rtype_div - def rtype_mod(_, hop): - return _rtype_template(hop, 'mod') - - rtype_inplace_mod = rtype_mod - def rtype_pow(_, hop): s_float3 = hop.args_s[2] if s_float3.is_constant() and s_float3.const is None: 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 Sat Oct 15 14:55:43 2005 @@ -28,7 +28,6 @@ #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) /*** conversions ***/ From lac at codespeak.net Sat Oct 15 15:10:06 2005 From: lac at codespeak.net (lac at codespeak.net) Date: Sat, 15 Oct 2005 15:10:06 +0200 (CEST) Subject: [pypy-svn] r18625 - pypy/dist/pypy/doc Message-ID: <20051015131006.8D3CD27B48@code1.codespeak.net> Author: lac Date: Sat Oct 15 15:10:05 2005 New Revision: 18625 Modified: pypy/dist/pypy/doc/architecture.txt Log: fix grammatical error Modified: pypy/dist/pypy/doc/architecture.txt ============================================================================== --- pypy/dist/pypy/doc/architecture.txt (original) +++ pypy/dist/pypy/doc/architecture.txt Sat Oct 15 15:10:05 2005 @@ -152,7 +152,7 @@ when add works on built-in sequences. All object-space operations take and return `application-level`_ objects. -There are only a few, very simple, object-space operation which allows the +There are only a few, very simple, object-space operations which allow the 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 From arigo at codespeak.net Sat Oct 15 15:10:42 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 15:10:42 +0200 (CEST) Subject: [pypy-svn] r18626 - in pypy/dist/pypy: objspace/flow objspace/std rpython translator/c/test Message-ID: <20051015131042.925C227B48@code1.codespeak.net> Author: arigo Date: Sat Oct 15 15:10:41 2005 New Revision: 18626 Modified: pypy/dist/pypy/objspace/flow/objspace.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/translator/c/test/test_annotated.py Log: unichr(too_big) => ValueError. Note that "too big" means greater than sys.maxunicode, which is still taken from the underlying CPython. Modified: pypy/dist/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/objspace.py (original) +++ pypy/dist/pypy/objspace/flow/objspace.py Sat Oct 15 15:10:41 2005 @@ -437,6 +437,7 @@ implicit_exceptions = { int: [ValueError], # built-ins that can always raise exceptions chr: [ValueError], + unichr: [ValueError], } def _add_exceptions(names, exc): Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Sat Oct 15 15:10:41 2005 @@ -337,8 +337,8 @@ try: chars = [unichr(c) for c in chars] except ValueError, e: # unichr(out-of-range) - raise OperationError(self.w_ValueError, - self.wrap("character code not in range(0x110000)")) + msg = "character code not in range(%s)" % hex(sys.maxunicode+1) + raise OperationError(self.w_ValueError, self.wrap(msg)) return W_UnicodeObject(self, chars) def newseqiter(self, w_obj): Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Sat Oct 15 15:10:41 2005 @@ -1,3 +1,4 @@ +import sys from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.objspace import op_appendices @@ -220,6 +221,9 @@ def rtype_unichr(_, hop): vlist = hop.inputargs(Signed) + if hop.has_implicit_exception(ValueError): + hop.exception_is_here() + hop.gendirectcall(ll_check_unichr, vlist[0]) return hop.genop('cast_int_to_unichar', vlist, resulttype=UniChar) def rtype_is_true(self, hop): @@ -414,6 +418,12 @@ else: raise ValueError +def ll_check_unichr(n): + if 0 <= n <= sys.maxunicode: + return + else: + raise ValueError + # # _________________________ Conversions _________________________ Modified: pypy/dist/pypy/translator/c/test/test_annotated.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_annotated.py (original) +++ pypy/dist/pypy/translator/c/test/test_annotated.py Sat Oct 15 15:10:41 2005 @@ -188,3 +188,14 @@ assert fn(65) == 'Yes A' assert fn(256) == 'No' assert fn(-1) == 'No' + + def test_unichr(self): + def f(x=int): + try: + return ord(unichr(x)) + except ValueError: + return -42 + fn = self.getcompiled(f) + assert fn(65) == 65 + assert fn(-12) == -42 + assert fn(sys.maxint) == -42 From adim at codespeak.net Sat Oct 15 15:13:57 2005 From: adim at codespeak.net (adim at codespeak.net) Date: Sat, 15 Oct 2005 15:13:57 +0200 (CEST) Subject: [pypy-svn] r18627 - in pypy/dist/pypy: interpreter objspace/std Message-ID: <20051015131357.C1C6D27B48@code1.codespeak.net> Author: adim Date: Sat Oct 15 15:13:55 2005 New Revision: 18627 Modified: pypy/dist/pypy/interpreter/function.py pypy/dist/pypy/objspace/std/typeobject.py Log: (arre, adim) - fixed some __slots__ uncaught errors (still doens't work completely) - fixed bound/unbound messages Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Sat Oct 15 15:13:55 2005 @@ -267,10 +267,11 @@ w_class = self.w_class typename = w_class.getname(self.space, '?') if self.w_instance is None: - s = "" %(name, typename) + s = "" % (typename, name) return space.wrap(s) else: - info = "method %s of %s object" % (name, typename) + info = 'bound method %s.%s' % (typename, name) + # info = "method %s of %s object" % (name, typename) return self.w_instance.getrepr(self.space, info) def descr_method_getattribute(self, w_attr): Modified: pypy/dist/pypy/objspace/std/typeobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/typeobject.py (original) +++ pypy/dist/pypy/objspace/std/typeobject.py Sat Oct 15 15:13:55 2005 @@ -138,11 +138,26 @@ w_slots = dict_w['__slots__'] if space.is_true(space.isinstance(w_slots, space.w_str)): + if space.int_w(space.len(w_slots)) == 0: + raise OperationError(space.w_TypeError, + space.wrap('__slots__ must be identifiers')) slot_names_w = [w_slots] else: slot_names_w = space.unpackiterable(w_slots) for w_slot_name in slot_names_w: slot_name = space.str_w(w_slot_name) + # slot_name should be a valid identifier + if len(slot_name) == 0: + raise OperationError(space.w_TypeError, + space.wrap('__slots__ must be identifiers')) + first_char = slot_name[0] + if not first_char.isalpha() and first_char != '_': + raise OperationError(space.w_TypeError, + space.wrap('__slots__ must be identifiers')) + for c in slot_name: + if not c.isalnum() and c!= '_': + raise OperationError(space.w_TypeError, + space.wrap('__slots__ must be identifiers')) if slot_name == '__dict__': if wantdict or w_self.hasdict: raise OperationError(space.w_TypeError, From arigo at codespeak.net Sat Oct 15 15:19:49 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 15:19:49 +0200 (CEST) Subject: [pypy-svn] r18629 - pypy/dist/pypy/lib Message-ID: <20051015131949.DB05627B44@code1.codespeak.net> Author: arigo Date: Sat Oct 15 15:19:49 2005 New Revision: 18629 Modified: pypy/dist/pypy/lib/_file.py pypy/dist/pypy/lib/_sio.py Log: * turn the file's OSErrors into IOErrors. * minor bug with _closed not defined if the file fails to open. Modified: pypy/dist/pypy/lib/_file.py ============================================================================== --- pypy/dist/pypy/lib/_file.py (original) +++ pypy/dist/pypy/lib/_file.py Sat Oct 15 15:19:49 2005 @@ -78,6 +78,8 @@ Note: open() is an alias for file(). """ + _closed = True # Until the file is successfully opened + def __init__(self, name, mode='r', buffering=None): self.fd = None self._name = name @@ -122,7 +124,10 @@ flag |= O_BINARY if self.fd is None: - self.fd = os.open(self.name, flag) + try: + self.fd = os.open(self.name, flag) + except OSError, e: + raise IOError(*e.args) if basemode == 'a': try: os.lseek(self.fd, 0, 2) @@ -132,8 +137,6 @@ reading = basemode == 'r' or plus writing = basemode != 'r' or plus - self._closed = True # Until the file is successfully opened - self.softspace = 0 # Required according to file object docs self.encoding = None # This is not used internally by file objects Modified: pypy/dist/pypy/lib/_sio.py ============================================================================== --- pypy/dist/pypy/lib/_sio.py (original) +++ pypy/dist/pypy/lib/_sio.py Sat Oct 15 15:19:49 2005 @@ -99,25 +99,42 @@ self.fd = fd def seek(self, offset, whence=0): - os.lseek(self.fd, offset, whence) + try: + os.lseek(self.fd, offset, whence) + except OSError, e: + raise IOError(*e.args) def tell(self): - return os.lseek(self.fd, 0, 1) + try: + return os.lseek(self.fd, 0, 1) + except OSError, e: + raise IOError(*e.args) def read(self, n): - return os.read(self.fd, n) + try: + return os.read(self.fd, n) + except OSError, e: + raise IOError(*e.args) def write(self, data): - while data: - n = os.write(self.fd, data) - data = data[n:] + try: + while data: + n = os.write(self.fd, data) + data = data[n:] + except OSError, e: + raise IOError(*e.args) def close(self): - os.close(self.fd) + try: + os.close(self.fd) + except OSError, e: + raise IOError(*e.args) def truncate(self, size): try: os.ftruncate(self.fd, size) + except OSError, e: + raise IOError(*e.args) except AttributeError: raise NotImplementedError From hpk at codespeak.net Sat Oct 15 16:40:32 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 15 Oct 2005 16:40:32 +0200 (CEST) Subject: [pypy-svn] r18631 - pypy/extradoc/planning Message-ID: <20051015144032.0896127B48@code1.codespeak.net> Author: hpk Date: Sat Oct 15 16:40:30 2005 New Revision: 18631 Modified: pypy/extradoc/planning/phase2_projectactivities.txt Log: results of the saturday afternoon planning meeting at the Paris sprint covering phase 2 and some phase 3 sprint + conferences + workshop + ... plans. Modified: pypy/extradoc/planning/phase2_projectactivities.txt ============================================================================== --- pypy/extradoc/planning/phase2_projectactivities.txt (original) +++ pypy/extradoc/planning/phase2_projectactivities.txt Sat Oct 15 16:40:30 2005 @@ -2,44 +2,108 @@ Rough preparation draft for saturday-afternoon 20051015 meeting Paris ------------------------------------------------------------- +work group/pairing status +------------------------------ + +- ootypes / rtyper refactoring: + Boris reports: continued to refactor rypting into + non-ll specific and ll-specific parts. still a lot + of work to be done (currently you can specialize + an empty class with the oo-type system). + bert: squeak backend uses the oo-type system and + creates squeak class definitions. (oo-types are + built manually there at the moment). + +- socket module: + all the interface is wrapped/implemented at interpreter-level + and is reusing the underlying (cpython) socket module. There is + not translation/external function calls yet (which will introduce + platform issues). + +- numeric module: + started the basic Array type, you can construct such types that + contain floats or integers, and you can have efficient slices + (reusing the same underlying array). The base Array class + is not connected to storage, subclasses are (specific to floats/ints). + +- l3interpreter: + have a refined very-low-level flow graph model, and we can + pass in integers and do addition. also the l3intepreter + is translateable and passes tests. + +- compiler issues + ran the core compliancy tests (failing ones are mostly + due to missing weakref support). problem is that we + are having a mix of all slightly incorrect compiler + (or at least don't know if they/which are correct) + variations. It seems to make more sense to contribute the + whole astcompiler rather than trying to come up with patches + to the CPython version. + +- translation issues: + compliance tests start to run on pypy-c (test_builtin.py) + but there are likely more bugs/issues lurking. + christian is working on locality of references by + analysing flowgraphs. + +pypy technical task planning +---------------------------------- + +Identify tasks to be done in between sprints, start with +see paris-2005-possible-tasks.txt: + +- full compiler/parser integration + +- pypy-sync meetings should constantly track/amend/modify those + technical tasks and in general focus on technical issues + NOTE though: pypy-sync cannot focus too much on EU requirements + because it's a more open/community forum. + +- idea is to collect all larger tasks and bring plannings + to the pypy-sync meetings. Carl is going to do the next + pypy-sync meeting. Send plans/larger task plannings to + the moderators and don't wait until the moderator generates + the idea himself. + + sprints & conferences ------------------------- - - *5-11th December (?): - Meeting in Sweden? Change Maker?/G?tabergsgatan? - - A sprint around bruxelles might make sense, - holger is checking with bruxelles and Louvain-la-neuve - (near bruxelles) people for a sprint beginning of - december. Bea is checking with Mallorca/Barcelona - regarding the same time frame. Nothing definitive - yet, alas! + next sprint: 5-11th December in Sweden (Change Maker?/G?tabergsgatan?) + Gborg. + + *(10 th January eu review workshop) *23-29th January: CS Dep. of the Palma de Mallorca University/CS Dep. of the Barcelona University Bea check dates, Bruxelles/Louvain-la-neuve, Holger check dates), - *27-29th February: PyCon (24-26 Feb, 2006 Dallas, Texas, Presperint?, Holger) + *27-29th February: PyCon (24-26 Feb, 2006 Dallas, Texas, postsprint, + Michael/Holger, Armin, Christian, Bea), DEADLINE 30th October *April Japan: (1) April 23 to April 29, (2) April 30 to May 5, contact: Yutaka Niibe, - National Institute of AIST, Japan (FSIJ) Akihabara, Tokyo (Bea) - - *6-9th (?) July: Europython Cern (3-5th July (?) Swizerland, Michael/Holger?) + National Institute of AIST, Japan (FSIJ) Akihabara, Tokyo (Bea), venue for 32 people. + (However, check with the EU). + + * (IBM workshop possibly end June, holger) + *6-9th (?) July: Europython Cern (3-5th July maybe in Leysin (Armin) Swizerland, + and the post-sprint at CERN, Michael/Holger) - *21-27th August: University of Limerick/Ireland (Bea) + *21-27th August: University of Limerick/Ireland (Bea), maybe good possibility + to present pypy results to researchers. - *2-8th October: ? + * 2-8th October: ? + * November: closure sprint - Other possibilities: Romania, Switzerland (Leysin,Bern), Uganda (Nkozi) + Other possibilities: Romania, Switzerland (Leysin,Bern), Bristol, Uganda (Nkozi), bruxelles - Conference/y?talks planning: - HALF-FIXED:8th December 2005 Calibre/agile development workshop in + FIXED:27th October2005 PMI Chapter Sweden, methodology/PyPy talk in Link?ping (Bea) + + HALF-FIXED: 8th December 2005 Calibre/agile development workshop in Bruxelles, Bea, Holger, Alastair attending (or maybe just two persons). Bea coordinates (Alastair?). - FIXED:27th October2005 PMI Chapter Sweden, methodology/PyPy talk in Link?ping (Bea) - HALF-FIXED: CCC 27th-30th December Berlin (pypy technical talk accepted, non-technical talk pending, may be unlikely, holger is keeping contact) @@ -49,9 +113,9 @@ Holger/Bea do talks about PyPy - methodology and tehnical aspects FIXED: Solution Linux 2006 (31st Januray-2nd Feb): - Logilab will present PyPy in the "free software models" track. + Logilab will present PyPy in the "free software models" track in Paris. - OPEN: PyCon, 24th-26th Feburary: Holger wants to submit one or two proposals + OPEN: PyCon, 24th-26th Feburary: michael/holger/christian/armin want to submit one or two proposals and go there, also doing a py lib and/or pypy-sprint. Bea wants to submit methodology talk. Note that sprints are scheduled after the conf. DEADLINE: 30th October (in two weeks!) @@ -59,35 +123,23 @@ OPEN: 3 of March 2006 Sk?vde Sweden, CALIBRE Workshop on Distributed Development, Open Source & Industry- Opportunities, Suspicions, & Strategies (Bea) + OPEN: ACCU 19th-22nd April 2005 (michael, jacob) + Submission date:? + OPEN: XP 2006, 17-22th June 2006 Oulu Finland Submission date: 1 march 2006 (methodology talk/workshop?/Bea) OPEN: 3-5th July 2006 Europython Cern Switzerland Submission date: ? - OPEN: OOPSLA 2006 (no date?) - Submission date: ? + OPEN: OOPSLA 2006 (Samuele, Armin) + Submission date: probably 20th March 2006 OPEN: Calibre conferences OPEN: Agile Alliance conferences? Submission date: ? - OPEN: ACCU? - Submission date:? - -pypy technical task planning ----------------------------------- - -Identify tasks to be done in between sprints, start with -see paris-2005-possible-tasks.txt: - -- full compiler/parser integration - -- pypy-sync meetings should constantly track/amend/modify those - technical tasks and in general focus on technical issues - NOTE though: pypy-sync cannot focus too much on EU requirements - because it's a more open/community forum. EU-related Workpackage planning planning phase 2 ------------------------------------------------- @@ -127,39 +179,39 @@ Completion date: 16th Oct 2005 D04.1 Partial Python Impl: -Primary/Secondary:Jacob/? +Primary/Secondary: Jacob / Christian Completion date: D04.2 Complete Python Impl: -Primary/Secondary:Jacob? +Primary/Secondary: Jacob / Christian Completion date: D04.3 Parser report: -Primary/Secondary:Jacob? +Primary/Secondary: ludovic,adrien / Arre Completion date: D04.4 Release PyPy-research-tool: -Primary/Secondary:Jacob? +Primary/Secondary: Samuele / Ludovic Completion date: D05.1 Publish on translating a very-high-level description: -Primary/Secondary:Armin/ +Primary/Secondary: Armin / Michael Completion date: D05.2 A compiled, self-contained version of PyPy: -Primary/Secondary:Armin/ +Primary/Secondary: dfki/Anders L. / Jacob Completion date: D05.3 Publish on implementation with translation aspects: -Primary/Secondary:Armin/ +Primary/Secondary: Carl / Armin, Christian Completion date: D05.4 Publish on encapsulating low level language aspects: -Primary/Secondary:Armin +Primary/Secondary: Armin / holger Completion date: D14.1 Report about Milestone/Phase 1: -Primary/Secondary:Bea/Stephan +Primary/Secondary: Bea/Stephan Completion date:21th October 2005 Review planning: @@ -175,7 +227,7 @@ *9th December 2005: Periodic management/activity reports updated with all data but costs (Jacob//Bea) -*15th December 205: submit reports to EC/reviewers +*15th December 2005: submit reports to EC/reviewers (Stephan) *16th December 2005: all partners submit FORM C:s to DFKI (or communicate a new @@ -187,4 +239,4 @@ *15th of January 2006: submit FORM C:s to EC/PO and possible updated periodic management/ activity reports -(Stephan//Jacob,Bea \ No newline at end of file +(Stephan//Jacob,Bea From hpk at codespeak.net Sat Oct 15 16:41:40 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sat, 15 Oct 2005 16:41:40 +0200 (CEST) Subject: [pypy-svn] r18632 - pypy/extradoc/planning Message-ID: <20051015144140.3612527B48@code1.codespeak.net> Author: hpk Date: Sat Oct 15 16:41:38 2005 New Revision: 18632 Removed: pypy/extradoc/planning/phase2.txt Log: remove stale file From ac at codespeak.net Sat Oct 15 16:47:23 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 15 Oct 2005 16:47:23 +0200 (CEST) Subject: [pypy-svn] r18633 - pypy/dist/pypy/interpreter/astcompiler Message-ID: <20051015144723.C18B127B49@code1.codespeak.net> Author: ac Date: Sat Oct 15 16:47:23 2005 New Revision: 18633 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py Log: When comparing constants compare elements in tuples recursivly. Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Sat Oct 15 16:47:23 2005 @@ -688,12 +688,29 @@ list.append(name) return end + def _cmpConsts(self, w_left, w_right): + space = self.space + t = space.type(w_left) + if space.is_w(t, space.type(w_right)): + if space.is_w(t, space.w_tuple): + left_len = space.int_w(space.len(w_left)) + right_len = space.int_w(space.len(w_right)) + if left_len == right_len: + for i in range(left_len): + w_lefti = space.getitem(w_left, space.wrap(i)) + w_righti = space.getitem(w_right, space.wrap(i)) + if not self._cmpConsts(w_lefti, w_righti): + return False + return True + elif space.eq_w(w_left, w_right): + return True + return False + def _lookupConst(self, w_obj, list_w): space = self.space w_obj_type = space.type(w_obj) for i in range(len(list_w)): - cand_w = list_w[i] - if space.is_w(space.type(cand_w), w_obj_type) and space.eq_w(list_w[i], w_obj): + if self._cmpConsts(w_obj, list_w[i]): return i end = len(list_w) list_w.append(w_obj) From afa at codespeak.net Sat Oct 15 16:55:52 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 16:55:52 +0200 (CEST) Subject: [pypy-svn] r18634 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051015145552.08E5227B49@code1.codespeak.net> Author: afa Date: Sat Oct 15 16:55:48 2005 New Revision: 18634 Modified: pypy/dist/pypy/module/_socket/__init__.py pypy/dist/pypy/module/_socket/app_socket.py pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: valentino, afa: more socket. The socket type does not work yet. Modified: pypy/dist/pypy/module/_socket/__init__.py ============================================================================== --- pypy/dist/pypy/module/_socket/__init__.py (original) +++ pypy/dist/pypy/module/_socket/__init__.py Sat Oct 15 16:55:48 2005 @@ -9,11 +9,11 @@ 'herror' : 'app_socket.herror', 'gaierror' : 'app_socket.gaierror', 'timeout' : 'app_socket.timeout', - 'setdefaulttimeout' : 'app_socket.setdefaulttimeout', - 'getdefaulttimeout' : 'app_socket.getdefaulttimeout', } interpleveldefs = { + 'SocketType': 'interp_socket.getsockettype(space)', + 'socket' : 'interp_socket.getsockettype(space)', } for name in """ @@ -22,6 +22,7 @@ fromfd socketpair ntohs ntohl htons htonl inet_aton inet_ntoa inet_pton inet_ntop getaddrinfo getnameinfo + getdefaulttimeout setdefaulttimeout """.split(): if hasattr(_socket, name): Modified: pypy/dist/pypy/module/_socket/app_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/app_socket.py (original) +++ pypy/dist/pypy/module/_socket/app_socket.py Sat Oct 15 16:55:48 2005 @@ -1,10 +1,7 @@ """Implementation module for socket operations. -NOT_RPYTHON See the socket module for documentation.""" -defaulttimeout = -1 # Default timeout for new sockets - class error(Exception): pass @@ -22,20 +19,3 @@ socket = SocketType -def setdefaulttimeout(timeout): - if timeout is None: - timeout = -1.0 - else: - if timeout < 0.0: - raise ValueError, "Timeout value out of range" - - global defaulttimeout - defaulttimeout = timeout - -def getdefaulttimeout(): - timeout = defaulttimeout - - if timeout < 0.0: - return None - else: - return timeout Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sat Oct 15 16:55:48 2005 @@ -1,8 +1,10 @@ import socket, errno, sys +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.error import OperationError -from pypy.interpreter.gateway import W_Root -from pypy.interpreter.gateway import ObjSpace, NoneNotWrapped +from pypy.interpreter.gateway import W_Root, NoneNotWrapped +from pypy.interpreter.gateway import ObjSpace, interp2app if sys.platform == 'win32': WIN32_ERROR_MESSAGES = { @@ -77,15 +79,23 @@ w_module = space.getbuiltinmodule('_socket') if isinstance(e, socket.gaierror): - w_error = space.getattr(w_module, space.wrap('gaierror')) + w_errortype = space.getattr(w_module, space.wrap('gaierror')) elif isinstance(e, socket.herror): - w_error = space.getattr(w_module, space.wrap('gaierror')) + w_errortype = space.getattr(w_module, space.wrap('herror')) else: - w_error = space.getattr(w_module, space.wrap('error')) + w_errortype = space.getattr(w_module, space.wrap('error')) + + return OperationError(w_errortype, + space.wrap(errno), + space.wrap(msg)) + +def wrap_timeouterror(space): + + w_module = space.getbuiltinmodule('_socket') + w_error = space.getattr(w_module, space.wrap('timeout')) w_error = space.call_function(w_error, - space.wrap(errno), - space.wrap(msg)) + space.wrap("timed out")) return w_error def gethostname(space): @@ -338,3 +348,417 @@ raise wrap_socketerror(space, e) getnameinfo.unwrap_spec = [ObjSpace, W_Root, int] +# _____________________________________________________________ +# +# Timeout management + +class State: + def __init__(self, space): + self.space = space + + self.defaulttimeout = -1 # Default timeout for new sockets + +def getstate(space): + return space.fromcache(State) + +def setdefaulttimeout(space, w_timeout): + if space.is_w(w_timeout, space.w_None): + timeout = -1.0 + else: + timeout = space.float_w(w_timeout) + if timeout < 0.0: + raise OperationError(space.w_ValueError, + space.wrap("Timeout value out of range")) + + getstate(space).defaulttimeout = timeout +setdefaulttimeout.unwrap_spec = [ObjSpace, W_Root] + +def getdefaulttimeout(space): + timeout = getstate(space).defaulttimeout + + if timeout < 0.0: + return space.wrap(None) + else: + return space.wrap(timeout) +getdefaulttimeout.unwrap_spec = [ObjSpace] + +# _____________________________________________________________ +# +# The socket type + +def getsockettype(space): + return space.gettypeobject(Socket.typedef) + +def newsocket(space, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): + try: + socket.setdefaulttimeout(getstate(space).defaulttimeout) + fd = socket.socket(family, type, proto) + except socket.error, e: + raise wrap_socketerror(space, e) + return Socket(fd, family, type, proto) +descr_socket_init = interp2app(newsocket, + unwrap_spec=[ObjSpace, int, int, int]) + +class Socket(Wrappable): + "A wrappable box around an interp-level socket object." + + def __init__(self, fd, family, type, proto): + self.fd = fd + self.family = family + self.type = type + self.proto = proto + self.timeout = getstate(space).defaulttimeout + + def accept(self, space): + """accept() -> (socket object, address info) + + Wait for an incoming connection. Return a new socket representing the + connection, and the address of the client. For IP sockets, the address + info is a pair (hostaddr, port). + """ + try: + newfd, address = self.fd.accept() + except socket.error, e: + raise wrap_socketerror(space, e) + newsock = Socket(newfd, self.family, self.type, self.proto) + return space.wrap((newsock, address)) + accept.unwrap_spec = ['self', ObjSpace] + + def bind(self, space, w_addr): + """bind(address) + + Bind the socket to a local address. For IP sockets, the address is a + pair (host, port); the host must refer to the local host. For raw packet + sockets the address is a tuple (ifname, proto [,pkttype [,hatype]]) + """ + addr = space.unwrap(w_addr) + try: + self.fd.bind(adrr) + except socket.error, e: + raise wrap_socketerror(space, e) + bind.unwrap_spec = ['self', ObjSpace, W_Root] + + def close(self, space): + """close() + + Close the socket. It cannot be used after this call. + """ + if self.fd is not None: + fd = self.fd + self.fd = None + fd.close() + close.unwrap_spec = ['self', ObjSpace] + + def connect(self, space, w_addr): + """connect(address) + + Connect the socket to a remote address. For IP sockets, the address + is a pair (host, port). + """ + addr = space.unwrap(w_addr) + try: + self.fd.connect(addr) + except timeout: + raise wrap_timeout(space) + except socket.error, e: + raise wrap_socketerror(space, e) + connect.unwrap_spec = ['self', ObjSpace, W_Root] + + def connect_ex(self, space, w_addr): + """connect_ex(address) -> errno + + This is like connect(address), but returns an error code (the errno value) + instead of raising an exception when an error occurs. + """ + addr = space.unwrap(w_addr) + try: + self.fd.connect(addr) + except socket.error, e: + return space.wrap(e.errno) + connect_ex.unwrap_spec = ['self', ObjSpace, W_Root] + + def dup(self, space): + """dup() -> socket object + + Return a new socket object connected to the same system resource. + """ + try: + newfd = self.fd.dup() + except socket.error, e: + raise wrap_socketerror(space, e) + newsock = Socket(newfd, self.family, self.type, self.proto) + return space.wrap(newsock) + dup.unwrap_spec = ['self', ObjSpace] + + def fileno(self, space): + """fileno() -> integer + + Return the integer file descriptor of the socket. + """ + return space.wrap(self.fd.fileno()) + fileno.unwrap_spec = ['self', ObjSpace] + + def getpeername(self, space): + """getpeername() -> address info + + Return the address of the remote endpoint. For IP sockets, the address + info is a pair (hostaddr, port). + """ + try: + return space.wrap(self.fd.getpeername()) + except socket.error, e: + raise wrap_socketerror(space, e) + getpeername.unwrap_spec = ['self', ObjSpace] + + def getsockname(self, space): + """getsockname() -> address info + + Return the address of the local endpoint. For IP sockets, the address + info is a pair (hostaddr, port). + """ + try: + return space.wrap(self.fd.getsockname()) + except socket.error, e: + raise wrap_socketerror(space, e) + getsockname.unwrap_spec = ['self', ObjSpace] + + def getsockopt(self, space, level, option, w_buffersize=NoneNotWrapped): + """getsockopt(level, option[, buffersize]) -> value + + Get a socket option. See the Unix manual for level and option. + If a nonzero buffersize argument is given, the return value is a + string of that length; otherwise it is an integer. + """ + try: + if w_buffersize is None: + return space.wrap(self.fd.getsockopt(level, option)) + else: + buffersize = space.int_w(w_buffersize) + return space.wrap(self.fd.getsockopt(level, option, buffersize)) + except socket.error, e: + raise wrap_socketerror(space, e) + getsockopt.unwrap_spec = ['self', ObjSpace, int, int, W_Root] + + def listen(self, space, backlog): + """listen(backlog) + + Enable a server to accept connections. The backlog argument must be at + least 1; it specifies the number of unaccepted connection that the system + will allow before refusing new connections. + """ + try: + self.fd.listen(backlog) + except socket.error, e: + raise wrap_socketerror(space, e) + listen.unwrap_spec = ['self', ObjSpace, int] + + def makefile(self, space, mode="r", buffersize=-1): + """makefile([mode[, buffersize]]) -> file object + + Return a regular file object corresponding to the socket. + The mode and buffersize arguments are as for the built-in open() function. + """ + try: + f = self.fd.makefile(mode, buffersize) + except socket.error, e: + raise wrap_socketerror(space, e) + return f + makefile.unwrap_spec = ['self', ObjSpace, str, int] + + def recv(self, space, buffersize, flags=0): + """recv(buffersize[, flags]) -> data + + Receive up to buffersize bytes from the socket. For the optional flags + argument, see the Unix manual. When no data is available, block until + at least one byte is available or until the remote end is closed. When + the remote end is closed and all data is read, return the empty string. + """ + try: + return space.wrap(self.fd.recv(buffersize, flags)) + except socket.error, e: + raise wrap_socketerror(space, e) + recv.unwrap_spec = ['self', ObjSpace, int, int] + + def recvfrom(self, space, buffersize, flags=0): + """recvfrom(buffersize[, flags]) -> (data, address info) + + Like recv(buffersize, flags) but also return the sender's address info. + """ + try: + return space.wrap(self.fd.recvfrom(buffersize, flags)) + except socket.error, e: + raise wrap_socketerror(space, e) + recvfrom.unwrap_spec = ['self', ObjSpace, int, int] + + def send(self, space, data, flags=0): + """send(data[, flags]) -> count + + Send a data string to the socket. For the optional flags + argument, see the Unix manual. Return the number of bytes + sent; this may be less than len(data) if the network is busy. + """ + try: + return space.wrap(self.fd.send(data, flags)) + except socket.error, e: + raise wrap_socketerror(space, e) + send.unwrap_spec = ['self', ObjSpace, str, int] + + def sendall(self, space, data, flags=0): + """sendall(data[, flags]) + + Send a data string to the socket. For the optional flags + argument, see the Unix manual. This calls send() repeatedly + until all data is sent. If an error occurs, it's impossible + to tell how much data has been sent. + """ + try: + self.fd.sendall(data, flags) + except socket.error, e: + raise wrap_socketerror(space, e) + sendall.unwrap_spec = ['self', ObjSpace, str, int] + + def sendto(self, space, data, w_param2, w_param3=NoneNotWrapped): + """sendto(data[, flags], address) -> count + + Like send(data, flags) but allows specifying the destination address. + For IP sockets, the address is a pair (hostaddr, port). + """ + if w_param3 is None: + # 2 args version + flags = 0 + addr = space.str_w(w_param2) + else: + # 3 args version + flags = space.int_w(w_param2) + addr = space.str_w(w_param3) + try: + self.fd.sendto(data, flags, addr) + except socket.error, e: + raise wrap_socketerror(space, e) + sendto.unwrap_spec = ['self', ObjSpace, str, W_Root, W_Root] + + def setblocking(self, space, flag): + """setblocking(flag) + + Set the socket to blocking (flag is true) or non-blocking (false). + setblocking(True) is equivalent to settimeout(None); + setblocking(False) is equivalent to settimeout(0.0). + """ + if flag: + self.settimeout(space, None) + else: + self.settimeout(space, 0.0) + setblocking.unwrap_spec = ['self', ObjSpace, int] + + def setsockopt(self, space, level, option, w_value): + """setsockopt(level, option, value) + + Set a socket option. See the Unix manual for level and option. + The value argument can either be an integer or a string. + """ + + if space.isinstance(w_value, space.w_string): + strvalue = space.str_w(w_value) + self.fd.setsockopt(level, option, strvalue) + else: + intvalue = space.int_w(w_value) + self.fd.setsockopt(level, option, intvalue) + setsockopt.unwrap_spec = ['self', ObjSpace, int, int, W_Root] + + def gettimeout(self, space): + """gettimeout() -> timeout + + Returns the timeout in floating seconds associated with socket + operations. A timeout of None indicates that timeouts on socket + operations are disabled. + """ + if self.timeout < 0.0: + return space.w_None + else: + return space.wrap(self.timeout) + gettimeout.unwrap_spec = ['self', ObjSpace] + + def settimeout(self, space, w_timeout): + """settimeout(timeout) + + Set a timeout on socket operations. 'timeout' can be a float, + giving in seconds, or None. Setting a timeout of None disables + the timeout feature and is equivalent to setblocking(1). + Setting a timeout of zero is the same as setblocking(0). + """ + if space.is_w(w_timeout, space.w_None): + timeout = -1.0 + else: + timeout = space.float_w(w_timeout) + if timeout < 0.0: + raise OperationError(space.w_ValueError, + space.wrap("Timeout value out of range")) + + self.timeout = timeout + self.fd.settimeout(timeout) + settimeout.unwrap_spec = ['self', ObjSpace, W_Root] + + def shutdown(self, space, how): + """shutdown(flag) + + Shut down the reading side of the socket (flag == SHUT_RD), the + writing side of the socket (flag == SHUT_WR), or both ends + (flag == SHUT_RDWR). + """ + self.fd.shutdown(how) + shutdown.unwrap_spec = ['self', ObjSpace, int] + +socketmethods = {} +for methodname in dir(Socket): + if methodname in dir(Wrappable): + continue + if methodname.startswith('_'): + continue + method = getattr(Socket, methodname) + if not callable(method): + continue + assert hasattr(method,'unwrap_spec'), methodname + assert method.im_func.func_code.co_argcount == len(method.unwrap_spec), methodname + socketmethods[methodname] = interp2app(method, method.unwrap_spec) + +Socket.typedef = TypeDef("_socket.socket", + __doc__ = """\ +socket([family[, type[, proto]]]) -> socket object + +Open a socket of the given type. The family argument specifies the +address family; it defaults to AF_INET. The type argument specifies +whether this is a stream (SOCK_STREAM, this is the default) +or datagram (SOCK_DGRAM) socket. The protocol argument defaults to 0, +specifying the default protocol. Keyword arguments are accepted. + +A socket object represents one endpoint of a network connection. + +Methods of socket objects (keyword arguments not allowed): + +accept() -- accept a connection, returning new socket and client address +bind(addr) -- bind the socket to a local address +close() -- close the socket +connect(addr) -- connect the socket to a remote address +connect_ex(addr) -- connect, return an error code instead of an exception +dup() -- return a new socket object identical to the current one [*] +fileno() -- return underlying file descriptor +getpeername() -- return remote address [*] +getsockname() -- return local address +getsockopt(level, optname[, buflen]) -- get socket options +gettimeout() -- return timeout or None +listen(n) -- start listening for incoming connections +makefile([mode, [bufsize]]) -- return a file object for the socket [*] +recv(buflen[, flags]) -- receive data +recvfrom(buflen[, flags]) -- receive data and sender's address +sendall(data[, flags]) -- send all data +send(data[, flags]) -- send data, may not send all of it +sendto(data[, flags], addr) -- send data to a given address +setblocking(0 | 1) -- set or clear the blocking I/O flag +setsockopt(level, optname, value) -- set socket options +settimeout(None | float) -- set or clear the timeout +shutdown(how) -- shut down traffic in one or both directions + + [*] not available on all platforms!""", + __init__ = descr_socket_init, + **socketmethods + ) Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Sat Oct 15 16:55:48 2005 @@ -173,7 +173,11 @@ w_t = space.appexec([w_socket], "(_socket): return _socket.getdefaulttimeout()") assert space.unwrap(w_t) is None - - - - + +class AppTestSocket: + def setup_class(cls): + cls.space = space + + def INPROGRESStest_newsocket(self): + import _socket + s = _socket.socket() From afa at codespeak.net Sat Oct 15 16:59:31 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 16:59:31 +0200 (CEST) Subject: [pypy-svn] r18635 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20051015145931.876B227B49@code1.codespeak.net> Author: afa Date: Sat Oct 15 16:59:29 2005 New Revision: 18635 Added: pypy/dist/lib-python/modified-2.4.1/test/test_socket.py Log: modified test_socket, to remove weakref related test Added: pypy/dist/lib-python/modified-2.4.1/test/test_socket.py ============================================================================== --- (empty file) +++ pypy/dist/lib-python/modified-2.4.1/test/test_socket.py Sat Oct 15 16:59:29 2005 @@ -0,0 +1,836 @@ +#!/usr/bin/env python +# Modified for pypy: removed weakrefs + +import unittest +from test import test_support + +import socket +import select +import time +import thread, threading +import Queue +import sys + +PORT = 50007 +HOST = 'localhost' +MSG = 'Michael Gilfix was here\n' + +class SocketTCPTest(unittest.TestCase): + + def setUp(self): + self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.serv.bind((HOST, PORT)) + self.serv.listen(1) + + def tearDown(self): + self.serv.close() + self.serv = None + +class SocketUDPTest(unittest.TestCase): + + def setUp(self): + self.serv = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.serv.bind((HOST, PORT)) + + def tearDown(self): + self.serv.close() + self.serv = None + +class ThreadableTest: + """Threadable Test class + + The ThreadableTest class makes it easy to create a threaded + client/server pair from an existing unit test. To create a + new threaded class from an existing unit test, use multiple + inheritance: + + class NewClass (OldClass, ThreadableTest): + pass + + This class defines two new fixture functions with obvious + purposes for overriding: + + clientSetUp () + clientTearDown () + + Any new test functions within the class must then define + tests in pairs, where the test name is preceeded with a + '_' to indicate the client portion of the test. Ex: + + def testFoo(self): + # Server portion + + def _testFoo(self): + # Client portion + + Any exceptions raised by the clients during their tests + are caught and transferred to the main thread to alert + the testing framework. + + Note, the server setup function cannot call any blocking + functions that rely on the client thread during setup, + unless serverExplicityReady() is called just before + the blocking call (such as in setting up a client/server + connection and performing the accept() in setUp(). + """ + + def __init__(self): + # Swap the true setup function + self.__setUp = self.setUp + self.__tearDown = self.tearDown + self.setUp = self._setUp + self.tearDown = self._tearDown + + def serverExplicitReady(self): + """This method allows the server to explicitly indicate that + it wants the client thread to proceed. This is useful if the + server is about to execute a blocking routine that is + dependent upon the client thread during its setup routine.""" + self.server_ready.set() + + def _setUp(self): + self.server_ready = threading.Event() + self.client_ready = threading.Event() + self.done = threading.Event() + self.queue = Queue.Queue(1) + + # Do some munging to start the client test. + methodname = self.id() + i = methodname.rfind('.') + methodname = methodname[i+1:] + test_method = getattr(self, '_' + methodname) + self.client_thread = thread.start_new_thread( + self.clientRun, (test_method,)) + + self.__setUp() + if not self.server_ready.isSet(): + self.server_ready.set() + self.client_ready.wait() + + def _tearDown(self): + self.__tearDown() + self.done.wait() + + if not self.queue.empty(): + msg = self.queue.get() + self.fail(msg) + + def clientRun(self, test_func): + self.server_ready.wait() + self.client_ready.set() + self.clientSetUp() + if not callable(test_func): + raise TypeError, "test_func must be a callable function" + try: + test_func() + except Exception, strerror: + self.queue.put(strerror) + self.clientTearDown() + + def clientSetUp(self): + raise NotImplementedError, "clientSetUp must be implemented." + + def clientTearDown(self): + self.done.set() + thread.exit() + +class ThreadedTCPSocketTest(SocketTCPTest, ThreadableTest): + + def __init__(self, methodName='runTest'): + SocketTCPTest.__init__(self, methodName=methodName) + ThreadableTest.__init__(self) + + def clientSetUp(self): + self.cli = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + + def clientTearDown(self): + self.cli.close() + self.cli = None + ThreadableTest.clientTearDown(self) + +class ThreadedUDPSocketTest(SocketUDPTest, ThreadableTest): + + def __init__(self, methodName='runTest'): + SocketUDPTest.__init__(self, methodName=methodName) + ThreadableTest.__init__(self) + + def clientSetUp(self): + self.cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + +class SocketConnectedTest(ThreadedTCPSocketTest): + + def __init__(self, methodName='runTest'): + ThreadedTCPSocketTest.__init__(self, methodName=methodName) + + def setUp(self): + ThreadedTCPSocketTest.setUp(self) + # Indicate explicitly we're ready for the client thread to + # proceed and then perform the blocking call to accept + self.serverExplicitReady() + conn, addr = self.serv.accept() + self.cli_conn = conn + + def tearDown(self): + self.cli_conn.close() + self.cli_conn = None + ThreadedTCPSocketTest.tearDown(self) + + def clientSetUp(self): + ThreadedTCPSocketTest.clientSetUp(self) + self.cli.connect((HOST, PORT)) + self.serv_conn = self.cli + + def clientTearDown(self): + self.serv_conn.close() + self.serv_conn = None + ThreadedTCPSocketTest.clientTearDown(self) + +class SocketPairTest(unittest.TestCase, ThreadableTest): + + def __init__(self, methodName='runTest'): + unittest.TestCase.__init__(self, methodName=methodName) + ThreadableTest.__init__(self) + + def setUp(self): + self.serv, self.cli = socket.socketpair() + + def tearDown(self): + self.serv.close() + self.serv = None + + def clientSetUp(self): + pass + + def clientTearDown(self): + self.cli.close() + self.cli = None + ThreadableTest.clientTearDown(self) + + +####################################################################### +## Begin Tests + +class GeneralModuleTests(unittest.TestCase): + + def Skip_test_weakref(self): + s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + p = proxy(s) + self.assertEqual(p.fileno(), s.fileno()) + s.close() + s = None + try: + p.fileno() + except ReferenceError: + pass + else: + self.fail('Socket proxy still exists') + + def testSocketError(self): + # Testing socket module exceptions + def raise_error(*args, **kwargs): + raise socket.error + def raise_herror(*args, **kwargs): + raise socket.herror + def raise_gaierror(*args, **kwargs): + raise socket.gaierror + self.failUnlessRaises(socket.error, raise_error, + "Error raising socket exception.") + self.failUnlessRaises(socket.error, raise_herror, + "Error raising socket exception.") + self.failUnlessRaises(socket.error, raise_gaierror, + "Error raising socket exception.") + + def testCrucialConstants(self): + # Testing for mission critical constants + socket.AF_INET + socket.SOCK_STREAM + socket.SOCK_DGRAM + socket.SOCK_RAW + socket.SOCK_RDM + socket.SOCK_SEQPACKET + socket.SOL_SOCKET + socket.SO_REUSEADDR + + def testHostnameRes(self): + # Testing hostname resolution mechanisms + hostname = socket.gethostname() + try: + ip = socket.gethostbyname(hostname) + except socket.error: + # Probably name lookup wasn't set up right; skip this test + return + self.assert_(ip.find('.') >= 0, "Error resolving host to ip.") + try: + hname, aliases, ipaddrs = socket.gethostbyaddr(ip) + except socket.error: + # Probably a similar problem as above; skip this test + return + all_host_names = [hostname, hname] + aliases + fqhn = socket.getfqdn() + if not fqhn in all_host_names: + self.fail("Error testing host resolution mechanisms.") + + def testRefCountGetNameInfo(self): + # Testing reference count for getnameinfo + import sys + if hasattr(sys, "getrefcount"): + try: + # On some versions, this loses a reference + orig = sys.getrefcount(__name__) + socket.getnameinfo(__name__,0) + except SystemError: + if sys.getrefcount(__name__) <> orig: + self.fail("socket.getnameinfo loses a reference") + + def testInterpreterCrash(self): + # Making sure getnameinfo doesn't crash the interpreter + try: + # On some versions, this crashes the interpreter. + socket.getnameinfo(('x', 0, 0, 0), 0) + except socket.error: + pass + + def testNtoH(self): + # This just checks that htons etc. are their own inverse, + # when looking at the lower 16 or 32 bits. + sizes = {socket.htonl: 32, socket.ntohl: 32, + socket.htons: 16, socket.ntohs: 16} + for func, size in sizes.items(): + mask = (1L< Author: tismer Date: Sat Oct 15 17:14:03 2005 New Revision: 18636 Modified: pypy/dist/pypy/doc/coding-guide.txt Log: small update on list usage rules. Didn't put too much effort here, please read and blame me! Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Sat Oct 15 17:14:03 2005 @@ -154,6 +154,18 @@ operator are allowed and efficient. Repetition via `*` or `*=` is fully supported as well. + - *indexing* + negative indexes are disallowed. Indexes are checked when requested + by an IndexError exception clause. + + - *slicing* + the slice start must be within bounds. The stop doesn't need to. + Negative indexes are disallowed, except for the [:-1] special case. + + - *insert* + the index must be withing bounds (not checked) and must not be negative + (checked at compile-time). + **dicts** dicts with a unique key type only, provided it is hashable. From bert at codespeak.net Sat Oct 15 17:17:58 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Sat, 15 Oct 2005 17:17:58 +0200 (CEST) Subject: [pypy-svn] r18637 - in pypy/dist/pypy/translator/squeak: . test Message-ID: <20051015151758.3566027B57@code1.codespeak.net> Author: bert Date: Sat Oct 15 17:17:58 2005 New Revision: 18637 Added: pypy/dist/pypy/translator/squeak/test/test_oo.py (contents, props changed) Modified: pypy/dist/pypy/translator/squeak/gensqueak.py Log: generate classes in backend, placeholders for methods Modified: pypy/dist/pypy/translator/squeak/gensqueak.py ============================================================================== --- pypy/dist/pypy/translator/squeak/gensqueak.py (original) +++ pypy/dist/pypy/translator/squeak/gensqueak.py Sat Oct 15 17:17:58 2005 @@ -9,6 +9,8 @@ selectormap = { 'setitem:with:': 'at:put:', 'getitem:': 'at:', + 'new': 'new', + 'sameAs': 'yourself', } def camel_case(str): @@ -80,6 +82,9 @@ } self.seennames = {} self.pendingfunctions = [] + self.pendingclasses = [] + self.pendingmethods = [] + self.classes = [] self.methods = [] t = self.translator @@ -98,9 +103,40 @@ def gen_source(self, file): - while self.pendingfunctions: - func = self.pendingfunctions.pop() - self.gen_sqfunction(func, file) + while self.pendingfunctions or self.pendingclasses or self.pendingmethods: + while self.pendingfunctions: + func = self.pendingfunctions.pop() + self.gen_sqfunction(func, file) + while self.pendingclasses: + inst = self.pendingclasses.pop() + self.gen_sqclass(inst, file) + while self.pendingmethods: + (inst, meth) = self.pendingmethods.pop() + self.gen_sqmethod(inst, meth, file) + + def gen_sqclass(self, inst, f): + self.classes.append(inst) + print >> f, """%s subclass: #%s + instanceVariableNames: '%s' + classVariableNames: '' + poolDictionaries: '' + category: 'PyPy-Test'! + """ % ( + self.nameof_Instance(inst._superclass), + self.nameof_Instance(inst), + ' '.join(inst._fields.iterkeys())) + + def gen_sqmethod(self, inst, meth, f): + if (inst, meth) in self.methods: + return + self.methods.append((inst, meth)) + print >> f, "!%s methodsFor: 'methods' stamp: 'pypy 1/1/2000 00:00'!" % ( + self.nameof_Instance(inst)) + print >> f, "%s" % meth + print >> f, ' "XXX methods not generated yet"' + print >> f, "! !" + print >> f + def gen_sqfunction(self, func, f): @@ -114,17 +150,21 @@ def oper(op): args = [expr(arg) for arg in op.args] - name = 'py_'+op.opname - receiver = args[0] - args = args[1:] + if op.opname == "oosend": + name = args[0] + receiver = args[1] + args = args[2:] + self.note_meth(op.args[1].concretetype, name) + else: + name = op.opname + receiver = args[0] + args = args[1:] argnames = ['with'] * len(args) if argnames: argnames[0] = '' sel = selector(name, argnames) - try: - sel = selectormap[sel] - except KeyError: - pass + if op.opname != "oosend": + sel = selectormap.get(sel, sel) return "%s := %s %s." % (expr(op.result), receiver, signature(sel, args)) def render_return(args): @@ -140,26 +180,13 @@ def render_link(link): block = link.target -# if len(block.exits) == 0: -# #short-cut return block -# for line in render_return(link.args): -# yield line -# return if link.args: -# yield '| %s |' % repr(block.inputargs[0]) for i in range(len(link.args)): yield '%s := %s.' % (expr(block.inputargs[i]), expr(link.args[i])) for line in render_block(block): yield line def render_block(block): - #yield '"%s"' % repr(block) -# temps = [] -# for op in block.operations: -# if isinstance(op.result, Variable): -# temps.append(expr(op.result)) -# if temps: -# yield "| %s | " % ' '.join(temps) if loops.has_key(block): if not loops[block]: yield '"skip1"' @@ -206,7 +233,7 @@ loops = LoopFinder(start).loops for line in render_block(start): - print >> f, ' %s' % line + print >> f, ' %s' % line print >> f def nameof(self, obj): @@ -214,28 +241,27 @@ try: return self.sqnames[key] except KeyError: - if (type(obj).__module__ != '__builtin__' and - not isinstance(obj, type)): # skip user-defined metaclasses - # assume it's a user defined thingy - name = self.nameof_instance(obj) - else: - for cls in type(obj).__mro__: - meth = getattr(self, - 'nameof_' + cls.__name__.replace(' ', ''), - None) - if meth: - break - else: - types = ['nameof_'+t.__name__ for t in type(obj).mro()] - raise Exception, "nameof(%r): no method %s" % (obj, types) - name = meth(obj) + for cls in type(obj).__mro__: + meth = getattr(self, + 'nameof_' + cls.__name__.replace(' ', ''), + None) + if meth: + break + else: + types = ['nameof_'+t.__name__ for t in type(obj).__mro__] + raise Exception, "nameof(%r): no method %s" % (obj, types) + name = meth(obj) self.sqnames[key] = name return name def nameof_int(self, i): return str(i) + def nameof_str(self, s): + return s + def nameof_function(self, func): + #XXX this should actually be a StaticMeth printable_name = '(%s:%d) %s' % ( func.func_globals.get('__name__', '?'), func.func_code.co_firstlineno, @@ -255,6 +281,23 @@ self.pendingfunctions.append(func) return sel + def nameof_Instance(self, inst): + if inst is None: + #empty superclass + return "Object" + self.note_Instance(inst) + return "Py%s" % inst._name.capitalize() + + def note_Instance(self, inst): + if inst not in self.classes: + if inst not in self.pendingclasses: + self.pendingclasses.append(inst) + + def note_meth(self, inst, meth): + bm = (inst, meth) + if bm not in self.methods: + if bm not in self.pendingmethods: + self.pendingmethods.append(bm) def unique_name(self, basename): n = self.seennames.get(basename, 0) Added: pypy/dist/pypy/translator/squeak/test/test_oo.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/squeak/test/test_oo.py Sat Oct 15 17:17:58 2005 @@ -0,0 +1,37 @@ +from pypy.tool.udir import udir +from pypy.translator.squeak.gensqueak import GenSqueak +from pypy.translator.translator import Translator +from pypy.rpython.ootypesystem.ootype import * + + +def build_sqfunc(func, args=[], view=False): + try: func = func.im_func + except AttributeError: pass + t = Translator(func) + t.annotate(args) + t.specialize(type_system="ootype") + t.simplify() + if view: + t.view() + GenSqueak(udir, t) + + +C = Instance("test", None, {'a': (Signed, 3)}) +M = Meth([Signed], Signed) +def m_(self, b): + return self.a+b +m = meth(M, _name="m", _callable=m_) +addMethods(C, {"m": m}) + +def f_new(): + return new(C) + +def f_meth(): + c = new(C) + return c.m(5) + +def test_simple_new(): + build_sqfunc(f_new) + +def test_simple_meth(): + build_sqfunc(f_meth, view=False) From arigo at codespeak.net Sat Oct 15 17:27:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sat, 15 Oct 2005 17:27:46 +0200 (CEST) Subject: [pypy-svn] r18639 - in pypy/dist/pypy: interpreter/astcompiler objspace/std rpython Message-ID: <20051015152746.E280127B49@code1.codespeak.net> Author: arigo Date: Sat Oct 15 17:27:45 2005 New Revision: 18639 Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py pypy/dist/pypy/objspace/std/listobject.py pypy/dist/pypy/rpython/rlist.py Log: Disable list.insert() with a negative index at RPython level. It was just confusing because it didn't check if the result was within bounds, and using a negative index here is just confusing in Python anyway so don't do it. Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Sat Oct 15 17:27:45 2005 @@ -301,7 +301,7 @@ # XXX just do one for now # do swaps to get things in the right order goes_before, a_chain = constraints[0] - assert a_chain > goes_before + assert a_chain > goes_before >= 0 c = chains[a_chain] del chains[a_chain] chains.insert(goes_before, c) Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Sat Oct 15 17:27:45 2005 @@ -307,7 +307,15 @@ raise OperationError(space.w_TypeError,space.wrap("list objects are unhashable")) def list_insert__List_ANY_ANY(space, w_list, w_where, w_any): - w_list.wrappeditems.insert(space.int_w(w_where), w_any) + where = space.int_w(w_where) + length = len(w_list.wrappeditems) + if where < 0: + where += length + if where < 0: + where = 0 + elif where > length: + where = length + w_list.wrappeditems.insert(where, w_any) return space.w_None def list_append__List_ANY(space, w_list, w_any): Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Sat Oct 15 17:27:45 2005 @@ -129,7 +129,7 @@ elif arg1.nonneg: llfn = ll_insert_nonneg else: - llfn = ll_insert + raise TyperError("insert() index must be proven non-negative") hop.exception_cannot_occur() hop.gendirectcall(llfn, *args) @@ -440,11 +440,6 @@ i -= 1 items[index] = newitem -def ll_insert(l, index, newitem): - if index < 0: - index += l.length - ll_insert_nonneg(l, index, newitem) - def dum_checkidx(): pass def dum_nocheck(): pass def dum_inplace():pass From afa at codespeak.net Sat Oct 15 17:31:10 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 17:31:10 +0200 (CEST) Subject: [pypy-svn] r18640 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051015153110.21D6827B42@code1.codespeak.net> Author: afa Date: Sat Oct 15 17:31:08 2005 New Revision: 18640 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: valentino, afa: more socket tests pass... Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sat Oct 15 17:31:08 2005 @@ -389,20 +389,29 @@ def getsockettype(space): return space.gettypeobject(Socket.typedef) -def newsocket(space, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0): +def newsocket(space, w_subtype, family=socket.AF_INET, + type=socket.SOCK_STREAM, proto=0): + # sets the timeout for the CPython implementation + timeout = getstate(space).defaulttimeout + if timeout < 0.0: + socket.setdefaulttimeout(None) + else: + socket.setdefaulttimeout(timeout) + try: - socket.setdefaulttimeout(getstate(space).defaulttimeout) fd = socket.socket(family, type, proto) except socket.error, e: raise wrap_socketerror(space, e) - return Socket(fd, family, type, proto) -descr_socket_init = interp2app(newsocket, - unwrap_spec=[ObjSpace, int, int, int]) + sock = space.allocate_instance(Socket, w_subtype) + Socket.__init__(sock, space, fd, family, type, proto) + return space.wrap(sock) +descr_socket_new = interp2app(newsocket, + unwrap_spec=[ObjSpace, W_Root, int, int, int]) class Socket(Wrappable): "A wrappable box around an interp-level socket object." - def __init__(self, fd, family, type, proto): + def __init__(self, space, fd, family, type, proto): self.fd = fd self.family = family self.type = type @@ -433,7 +442,7 @@ """ addr = space.unwrap(w_addr) try: - self.fd.bind(adrr) + self.fd.bind(addr) except socket.error, e: raise wrap_socketerror(space, e) bind.unwrap_spec = ['self', ObjSpace, W_Root] @@ -657,7 +666,7 @@ The value argument can either be an integer or a string. """ - if space.isinstance(w_value, space.w_string): + if space.is_true(space.isinstance(w_value, space.w_str)): strvalue = space.str_w(w_value) self.fd.setsockopt(level, option, strvalue) else: @@ -708,15 +717,15 @@ self.fd.shutdown(how) shutdown.unwrap_spec = ['self', ObjSpace, int] +socketmethodnames = """ +accept bind close connect connect_ex dup fileno +getpeername getsockname getsockopt listen makefile recv +recvfrom send sendall sendto setblocking setsockopt gettimeout +settimeout shutdown +""".split() socketmethods = {} -for methodname in dir(Socket): - if methodname in dir(Wrappable): - continue - if methodname.startswith('_'): - continue +for methodname in socketmethodnames: method = getattr(Socket, methodname) - if not callable(method): - continue assert hasattr(method,'unwrap_spec'), methodname assert method.im_func.func_code.co_argcount == len(method.unwrap_spec), methodname socketmethods[methodname] = interp2app(method, method.unwrap_spec) @@ -759,6 +768,6 @@ shutdown(how) -- shut down traffic in one or both directions [*] not available on all platforms!""", - __init__ = descr_socket_init, + __new__ = descr_socket_new, **socketmethods ) Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Sat Oct 15 17:31:08 2005 @@ -178,6 +178,6 @@ def setup_class(cls): cls.space = space - def INPROGRESStest_newsocket(self): - import _socket - s = _socket.socket() + def test_newsocket(self): + import socket + s = socket.socket() From dialtone at codespeak.net Sat Oct 15 17:32:57 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Sat, 15 Oct 2005 17:32:57 +0200 (CEST) Subject: [pypy-svn] r18641 - pypy/dist/pypy/module/_socket Message-ID: <20051015153257.3CCEA27B42@code1.codespeak.net> Author: dialtone Date: Sat Oct 15 17:32:55 2005 New Revision: 18641 Modified: pypy/dist/pypy/module/_socket/interp_socket.py Log: (afa, valentino) fix under posix Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sat Oct 15 17:32:55 2005 @@ -69,6 +69,7 @@ def socket_strerror(errno): return WIN32_ERROR_MESSAGES.get(errno, "winsock error") else: + import os def socket_strerror(errno): return os.strerror(errno) From ac at codespeak.net Sat Oct 15 17:51:21 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Sat, 15 Oct 2005 17:51:21 +0200 (CEST) Subject: [pypy-svn] r18642 - in pypy/dist/pypy/interpreter: pyparser/test stablecompiler Message-ID: <20051015155121.F1A5B27B62@code1.codespeak.net> Author: ac Date: Sat Oct 15 17:51:21 2005 New Revision: 18642 Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py pypy/dist/pypy/interpreter/stablecompiler/transformer.py Log: Set correct lineno on List-nodes and re-enable test for it. 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 Sat Oct 15 17:51:21 2005 @@ -683,7 +683,7 @@ 'snippet_whitespaces.py', 'snippet_samples.py', 'snippet_decorators.py', - # 'snippet_listlinenos.py', + 'snippet_listlinenos.py', 'snippet_whilelineno.py', ] Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py ============================================================================== --- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original) +++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Sat Oct 15 17:51:21 2005 @@ -734,8 +734,8 @@ def atom_lsqb(self, nodelist): if nodelist[1][0] == token.RSQB: - return List([]) - return self.com_list_constructor(nodelist[1]) + return List([], lineno=nodelist[0][2]) + return self.com_list_constructor(nodelist[1], nodelist[0][2]) def atom_lbrace(self, nodelist): if nodelist[1][0] == token.RBRACE: @@ -1097,7 +1097,7 @@ stmts.append(result) if hasattr(symbol, 'list_for'): - def com_list_constructor(self, nodelist): + def com_list_constructor(self, nodelist, lineno): # listmaker: test ( list_for | (',' test)* [','] ) values = [] for i in range(1, len(nodelist)): @@ -1108,7 +1108,7 @@ elif nodelist[i][0] == token.COMMA: continue values.append(self.com_node(nodelist[i])) - return List(values, lineno=values[0].lineno) + return List(values, lineno=lineno) def com_list_comprehension(self, expr, node): # list_iter: list_for | list_if @@ -1149,11 +1149,11 @@ assert node[0] == symbol.list_iter return node[1] else: - def com_list_constructor(self, nodelist): + def com_list_constructor(self, nodelist, lineno): values = [] for i in range(1, len(nodelist), 2): values.append(self.com_node(nodelist[i])) - return List(values) + return List(values, lineno) if hasattr(symbol, 'gen_for'): def com_generator_expression(self, expr, node): From mwh at codespeak.net Sat Oct 15 18:04:06 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 18:04:06 +0200 (CEST) Subject: [pypy-svn] r18643 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20051015160406.DE2AC27B44@code1.codespeak.net> Author: mwh Date: Sat Oct 15 18:04:04 2005 New Revision: 18643 Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py Log: M-x untabify Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rootype.py Sat Oct 15 18:04:04 2005 @@ -21,33 +21,33 @@ def rtype_getattr(self, hop): attr = hop.args_s[1].const - s_inst = hop.args_s[0] - meth = self.lowleveltype._lookup(attr) - if meth is not None: - # just return instance - will be handled by simple_call - return hop.inputarg(hop.r_result, arg=0) - self.lowleveltype._check_field(attr) - vlist = hop.inputargs(self, Void) - return hop.genop("oogetfield", vlist, - resulttype = hop.r_result.lowleveltype) + s_inst = hop.args_s[0] + meth = self.lowleveltype._lookup(attr) + if meth is not None: + # just return instance - will be handled by simple_call + return hop.inputarg(hop.r_result, arg=0) + self.lowleveltype._check_field(attr) + vlist = hop.inputargs(self, Void) + return hop.genop("oogetfield", vlist, + resulttype = hop.r_result.lowleveltype) def rtype_setattr(self, hop): attr = hop.args_s[1].const - self.lowleveltype._check_field(attr) + self.lowleveltype._check_field(attr) vlist = hop.inputargs(self, Void, hop.args_r[2]) return hop.genop('oosetfield', vlist) class OOBoundMethRepr(Repr): def __init__(self, ootype, name): self.lowleveltype = ootype - self.name = name + self.name = name def rtype_simple_call(self, hop): - vlist = hop.inputargs(self, *hop.args_r[1:]) + vlist = hop.inputargs(self, *hop.args_r[1:]) cname = hop.inputconst(Void, self.name) - return hop.genop("oosend", [cname]+vlist, - resulttype = hop.r_result.lowleveltype) - + return hop.genop("oosend", [cname]+vlist, + resulttype = hop.r_result.lowleveltype) + class __extend__(pairtype(OOInstanceRepr, OOBoundMethRepr)): From mwh at codespeak.net Sat Oct 15 18:06:21 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 18:06:21 +0200 (CEST) Subject: [pypy-svn] r18644 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051015160621.C476227B44@code1.codespeak.net> Author: mwh Date: Sat Oct 15 18:06:15 2005 New Revision: 18644 Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: (mwh, boria, bert, even a little samuele) Add a test for a class with an instance attribute. Make it pass by writing more of InstanceRepr. Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sat Oct 15 18:06:15 2005 @@ -1,5 +1,6 @@ from pypy.rpython.rmodel import inputconst -from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr +from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \ + getclassrepr from pypy.rpython.ootypesystem import ootype CLASSTYPE = ootype.Class @@ -11,8 +12,7 @@ self.lowleveltype = ootype.Class def _setup_repr(self): - # FIXME to be completed - pass + pass # not actually needed? def convert_const(self): # FIXME @@ -26,8 +26,36 @@ self.prebuiltinstances = {} # { id(x): (x, _ptr) } def _setup_repr(self): - # FIXME fields, methods - pass + # FIXME methods + assert self.classdef.basedef is None + + fields = {} + attrs = self.classdef.attrs.items() + + for name, attrdef in attrs: + if not attrdef.readonly: + oot = self.rtyper.getrepr(attrdef.s_value).lowleveltype + fields[name] = oot + + ootype.addFields(self.lowleveltype, fields) + + def rtype_getattr(self, hop): + attr = hop.args_s[1].const + s_inst = hop.args_s[0] + meth = self.lowleveltype._lookup(attr) + if meth is not None: + # just return instance - will be handled by simple_call + return hop.inputarg(hop.r_result, arg=0) + self.lowleveltype._check_field(attr) + vlist = hop.inputargs(self, ootype.Void) + return hop.genop("oogetfield", vlist, + resulttype = hop.r_result.lowleveltype) + + def rtype_setattr(self, hop): + attr = hop.args_s[1].const + self.lowleveltype._check_field(attr) + vlist = hop.inputargs(self, ootype.Void, hop.args_r[2]) + return hop.genop('oosetfield', vlist) def convert_const(self): # FIXME Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sat Oct 15 18:06:15 2005 @@ -2,10 +2,14 @@ from pypy.rpython import lltype from pypy.rpython.ootypesystem import ootype -def specialize(f, input_types): +def specialize(f, input_types, viewBefore=False, viewAfter=False): t = Translator(f) t.annotate(input_types) + if viewBefore: + t.view() t.specialize(type_system="ootype") + if viewAfter: + t.view() graph = t.flowgraphs[f] check_only_ootype(graph) @@ -43,3 +47,12 @@ x = EmptyBase() return x specialize(dummyfn, []) + + +def test_instance_attribute(): + def dummyfn(): + x = EmptyBase() + x.a = 1 + return x.a + specialize(dummyfn, []) + From cfbolz at codespeak.net Sat Oct 15 18:14:41 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 15 Oct 2005 18:14:41 +0200 (CEST) Subject: [pypy-svn] r18645 - pypy/extradoc/sprintinfo Message-ID: <20051015161441.3F53827B48@code1.codespeak.net> Author: cfbolz Date: Sat Oct 15 18:14:36 2005 New Revision: 18645 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: just so that it does not get lost Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Sat Oct 15 18:14:36 2005 @@ -70,4 +70,5 @@ - Javascript frontend - support for developing C extensions for CPython with RPython code - +- writing a sort of flow object space for the llinterpreter + to experiment with JIT work From ludal at codespeak.net Sat Oct 15 18:15:29 2005 From: ludal at codespeak.net (ludal at codespeak.net) Date: Sat, 15 Oct 2005 18:15:29 +0200 (CEST) Subject: [pypy-svn] r18646 - pypy/dist/pypy/module/Numeric Message-ID: <20051015161529.7A61C27B46@code1.codespeak.net> Author: ludal Date: Sat Oct 15 18:15:27 2005 New Revision: 18646 Modified: pypy/dist/pypy/module/Numeric/__init__.py pypy/dist/pypy/module/Numeric/app_numeric.py pypy/dist/pypy/module/Numeric/interp_numeric.py Log: (ludal,aft) finished merging scalar, and multi indices versions array function Modified: pypy/dist/pypy/module/Numeric/__init__.py ============================================================================== --- pypy/dist/pypy/module/Numeric/__init__.py (original) +++ pypy/dist/pypy/module/Numeric/__init__.py Sat Oct 15 18:15:27 2005 @@ -13,6 +13,7 @@ # 'array' : 'interp_numeric.w_array', 'zeros' : 'interp_numeric.w_zeros', 'array' : 'interp_numeric.array', + 'ArrayType' : 'space.gettypeobject(interp_numeric.W_Array.typedef)', 'TOWER_TYPES' : 'space.wrap(interp_numeric.TOWER_TYPES)', 'TOWER_TYPES_VALUES' :'space.wrap(interp_numeric.TOWER_TYPES_VALUES)' } Modified: pypy/dist/pypy/module/Numeric/app_numeric.py ============================================================================== --- pypy/dist/pypy/module/Numeric/app_numeric.py (original) +++ pypy/dist/pypy/module/Numeric/app_numeric.py Sat Oct 15 18:15:27 2005 @@ -1,6 +1,6 @@ -from Numeric import zeros,array +from Numeric import zeros,array,ArrayType from Numeric import Float,TOWER_TYPES,TOWER_TYPES_VALUES @@ -21,9 +21,10 @@ """ #first we check the really simple, empty or minimal arrays +print "Checking scalars" assert (0,)==array(()).shape assert ()==array((1)).shape -assert array(()).isArray() and array((1)).isArray() +assert isinstance( array(()), ArrayType) and isinstance( array((1)), ArrayType ) #next we check the typecodes on these small examples assert 'l'==array(()).typecode() @@ -31,13 +32,15 @@ assert 'd'==array((1.0)).typecode() #we are not supporting complex numbers or any other objects yet -assertRaises(lambda :array((1j)),ValueError) -assertRaises(lambda :array((1j,)),ValueError) -assertRaises(lambda :array(('a')),ValueError) +print "checking unsupported types" +assertRaises(lambda :array((1j)),TypeError) +assertRaises(lambda :array((1j,)),TypeError) +assertRaises(lambda :array(('a')),TypeError) #now check accessing of values on empty array, and a scalar #assertRaises(lambda :array(())[0],IndexError +print "DONE" Modified: pypy/dist/pypy/module/Numeric/interp_numeric.py ============================================================================== --- pypy/dist/pypy/module/Numeric/interp_numeric.py (original) +++ pypy/dist/pypy/module/Numeric/interp_numeric.py Sat Oct 15 18:15:27 2005 @@ -34,7 +34,9 @@ n = 1 for d in dims: n *= d - assert d>0 + assert d>=0 + if n==0: + return 1 return n def is_integer( space, w_obj ): @@ -121,6 +123,9 @@ pass return self.set_slice( space, multi_idx, w_value ) + def descr_typecode(self,space): + return self.typecode(space) + def fget_shape( space, self ): return space.newtuple( [ self.space.wrap( i ) for i in self.dims ] ) @@ -133,6 +138,10 @@ idx += self.strides[i]*idx_tuple[i] return idx + def typecode(self,space): + raise OperationError( space.w_NotImplemented, + space.wrap("calling abstract base class" )) + class W_Array_Float(W_Array): @@ -181,128 +190,152 @@ array = W_Array_Float( space, dims, strides, self.storage ) return space.wrap(array) - -descr___getitem__ = interp2app( W_Array.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) -descr___setitem__ = interp2app( W_Array.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) - -W_Array.typedef = TypeDef("array", - shape = GetSetProperty( W_Array.fget_shape, cls=W_Array), - __getitem__ = descr___getitem__, - __setitem__ = descr___setitem__, - ) - -W_Array_Float.typedef = TypeDef("array_float", W_Array.typedef, - ) - -def w_zeros( space, w_dim_tuple, type_str ): - dims = [] - for w_int in space.unpackiterable(w_dim_tuple): - dims.append( space.unwrap( w_int ) ) - if type_str == 'd': - return space.wrap(W_Array_Float( space, dims )) - raise OperationError( space.w_ValueError, space.wrap('Unknown type code') ) - -w_zeros.unwrap_spec = [ ObjSpace, W_Root, str ] - - - - -""" -""" -class W_NumericArray(Wrappable): - - def __init__(self, space, dims ,value=None ): - self.space = space - self.dims = dims - self.value= value - - def check_space_true(self, space, w_index): - if not space.is_true(space.isinstance( w_index, space.w_int )): - raise NotImplementedError - idx = space.unwrap( w_index ) - assert isinstance( idx, int ) - return idx - - def isArray(self,space): - return self.space.wrap(True) - def typecode(self,space): - code='l' - if isinstance(self.value,float): - code='d' - return self.space.wrap(code) - - def descr___getitem__( self, space, w_index ): - return self.get_single_item( space, [ self.check_space_true( space, w_index)]) - - def descr___setitem__( self, space, w_index, w_value ): - return self.set_single_item( space, [ self.check_space_true( space, w_index) ], w_value ) + return space.wrap('d') - def fget_shape( space, self ): - return space.newtuple( [ self.space.wrap( i ) for i in self.dims ] ) +class W_Array_Integer(W_Array): - def fset_shape( space, self, w_tuple ): - pass - - def get_array_offset( self, idx_tuple ): - if len(idx_tuple)>len(self.dims): - # TODO raise OperationError - raise RuntimeError - idx = 0 - for i in range(len(idx_tuple)): - idx += self.strides[i]*idx_tuple[i] - return idx + def __init__(self, space, dims, strides=None, storage=None ): + W_Array.__init__(self, space, dims, strides ) + self.storage = [] + if storage is not None: + assert isinstance(storage, list) + # TODO return proper exception here + # assert len(storage)==storage_size ### can't check that because of slicing + assert isinstance(storage[0], int) + self.storage = storage + else: + storage_size = get_storage_size(dims) + self.storage = [0]*storage_size def get_single_item( self, space, idx_tuple ): if len(idx_tuple)!=len(self.dims): # TODO raise OperationError or remove this and make it a pre-condition raise RuntimeError + idx = self.get_array_offset( idx_tuple ) return space.wrap( self.storage[idx] ) def set_single_item( self, space, idx_tuple, w_value ): idx = self.get_array_offset( idx_tuple ) - value = space.float_w( w_value ) + value = space.int_w( w_value ) self.storage[idx] = value + def get_slice( self, space, multi_idx ): + # compute dim of extracted array + dims = [] + strides = [] + last_stride = 1 + offset = self.base_offset + for i in range(len(multi_idx)): + idx = multi_idx[i] + if isinstance( idx, SliceIndex): + start, stop, step = idx.indices( self.dims[i] ) + dim = (stop-start)//step + stride = self.strides[i]*step + dims.append( dim ) + strides.append( step ) + elif isinstance( idx, IntIndex ): + offset+= idx.index*self.strides[i] + array = W_Array_Float( space, dims, strides, self.storage ) + return space.wrap(array) + def typecode(self,space): + return space.wrap('l') -descr___getitem__ = interp2app( W_NumericArray.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) -descr___setitem__ = interp2app( W_NumericArray.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) - -isArray = interp2app( W_NumericArray.isArray, unwrap_spec=['self', ObjSpace ] ) -typecode = interp2app( W_NumericArray.typecode, unwrap_spec=['self', ObjSpace ] ) - - +descr___getitem__ = interp2app( W_Array.descr___getitem__, unwrap_spec=['self', ObjSpace, W_Root ] ) +descr___setitem__ = interp2app( W_Array.descr___setitem__, unwrap_spec=['self', ObjSpace, W_Root, W_Root ] ) +descr_typecode = interp2app( W_Array.descr_typecode, unwrap_spec=['self', ObjSpace ] ) -W_NumericArray.typedef = TypeDef("W_NumericArray", - shape = GetSetProperty( W_NumericArray.fget_shape, cls=W_NumericArray), - isArray = isArray, - typecode= typecode, +W_Array.typedef = TypeDef("array", + shape = GetSetProperty( W_Array.fget_shape, cls=W_Array), __getitem__ = descr___getitem__, __setitem__ = descr___setitem__, + typecode = descr_typecode, ) +#W_Array_Float.typedef = TypeDef("array", W_Array.typedef,) +#W_Array_Integer.typedef = TypeDef("array", W_Array.typedef, ) + + +def w_zeros( space, w_dim_tuple, type_str ): + dims = [] + for w_int in space.unpackiterable(w_dim_tuple): + dims.append( space.unwrap( w_int ) ) + if type_str == 'd': + return space.wrap(W_Array_Float( space, dims )) + raise OperationError( space.w_ValueError, space.wrap('Unknown type code') ) + +w_zeros.unwrap_spec = [ ObjSpace, W_Root, str ] + + TOWER_TYPES_VALUES=[(int,1),(float,1.0),(complex,2.0+3j)] #we will work with these types to start with TOWER_TYPES_VALUES=TOWER_TYPES_VALUES[0:2] #cannot unpack complex values yet at interp level. TOWER_TYPES=[typ for typ,val in TOWER_TYPES_VALUES] + + def OpError(space,w_arg): - raise OperationError( space.w_ValueError,space.wrap('Cannot unwrap this <%s>'%str(w_arg))) + raise OperationError( space.w_TypeError,space.wrap('Cannot unwrap this <%s>'%str(w_arg))) + + +def int_array_from_iterable( space, w_it ): + N = space.int_w(space.len( w_it )) + storage = N*[0] + i = 0 + for w_obj in space.unpackiterable( w_it ): + storage[i] = space.int_w( w_it ) + i+=1 + +def float_array_from_iterable( space, w_it ): + N = space.int_w(space.len( w_it )) + storage = N*[0.] + i = 0 + for w_obj in space.unpackiterable( w_it ): + storage[i] = space.float_w( w_it ) + i+=1 def array( space, w_arg): - try: - arg=space.unwrap( w_arg) - except: - OpError(space,w_arg) - if arg in ((),[]): - return W_NumericArray(space,(0,)) - if type(arg) not in (int,float): - OpError(space,w_arg) + TYPES = "ldD" + if (space.is_true( space.isinstance( w_arg, space.w_list ) ) or + space.is_true( space.isinstance( w_arg, space.w_tuple ) ) ): + if not space.is_true( w_arg ): + return W_Array_Integer(space,[0,]) + ty = -1 + for w_obj in space.unpackiterable( w_arg ): + if ty< 0 and space.is_true( space.isinstance( w_arg, space.w_int ) ): + ty = 0 + if ty< 1 and space.is_true( space.isinstance( w_arg, space.w_float ) ): + ty = 1 +## elif ty<2 and space.is_true( space.isinstance( w_arg, space.w_complex ) ): +## ty = 2 + else: + raise OperationError( space.w_TypeError, + space.wrap("Only int, float and complex currently supported") ) + if ty == 2: + break + if ty==0: + return int_array_from_iterable( space, w_arg ) + elif ty==1: + return float_array_from_iterable( space, w_arg ) + elif ty==2: + raise OperationError( space.w_NotImplementedError, + space.wrap("complex array not implemented") ) + else: + raise OperationError( space.w_TypeError, + space.wrap("Unknown array type") ) + + elif space.is_true( space.isinstance( w_arg, space.w_int ) ): + ivalue = space.int_w( w_arg ) + return W_Array_Integer(space, [], storage=[ivalue]) + elif space.is_true( space.isinstance( w_arg, space.w_float ) ): + fvalue = space.float_w( w_arg ) + return W_Array_Float(space, [], storage=[fvalue]) else: - return W_NumericArray(space,(),value=arg) + OpError(space,w_arg) + array.unwrap_spec = [ ObjSpace, W_Root ] From cfbolz at codespeak.net Sat Oct 15 18:17:12 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 15 Oct 2005 18:17:12 +0200 (CEST) Subject: [pypy-svn] r18647 - pypy/extradoc/sprintinfo Message-ID: <20051015161712.7A82827B46@code1.codespeak.net> Author: cfbolz Date: Sat Oct 15 18:17:00 2005 New Revision: 18647 Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Log: this one is done Modified: pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt (original) +++ pypy/extradoc/sprintinfo/paris-2005-possible-tasks.txt Sat Oct 15 18:17:00 2005 @@ -63,7 +63,7 @@ - PyPy option handling unification, passing py.py options to targetpypy* - inline (transforms in general) -- genc: producing multiple .h/.c files tracking Python code origin +- (DONE) genc: producing multiple .h/.c files tracking Python code origin Larger whole projects ---------------------- From mwh at codespeak.net Sat Oct 15 18:24:44 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 18:24:44 +0200 (CEST) Subject: [pypy-svn] r18648 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051015162444.0BE8927B48@code1.codespeak.net> Author: mwh Date: Sat Oct 15 18:24:38 2005 New Revision: 18648 Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: (boria, mwh, bert) some support for superclasses (no methods yet though) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sat Oct 15 18:24:38 2005 @@ -1,6 +1,6 @@ from pypy.rpython.rmodel import inputconst from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \ - getclassrepr + getinstancerepr from pypy.rpython.ootypesystem import ootype CLASSTYPE = ootype.Class @@ -22,12 +22,15 @@ def __init__(self, rtyper, classdef, does_need_gc=True): AbstractInstanceRepr.__init__(self, rtyper, classdef) - self.lowleveltype = ootype.Instance(classdef.cls.__name__, None, {}, {}) + b = self.classdef.basedef + if b is not None: + b = getinstancerepr(rtyper, b).lowleveltype + + self.lowleveltype = ootype.Instance(classdef.cls.__name__, b, {}, {}) self.prebuiltinstances = {} # { id(x): (x, _ptr) } def _setup_repr(self): # FIXME methods - assert self.classdef.basedef is None fields = {} attrs = self.classdef.attrs.items() Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sat Oct 15 18:24:38 2005 @@ -56,3 +56,17 @@ return x.a specialize(dummyfn, []) +class Subclass(EmptyBase): + pass + +def test_subclass_attributes(): + def dummyfn(): + x = EmptyBase() + x.a = 1 + y = Subclass() + y.a = 2 + y.b = 3 + return x.a + y.a + y.b + specialize(dummyfn, []) + + From afa at codespeak.net Sat Oct 15 19:01:53 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 19:01:53 +0200 (CEST) Subject: [pypy-svn] r18650 - in pypy/dist/pypy/module/_socket: . test Message-ID: <20051015170153.3489327B52@code1.codespeak.net> Author: afa Date: Sat Oct 15 19:01:51 2005 New Revision: 18650 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/test/test_socket2.py Log: valentino, afa: correct implementation of socket.htonl Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sat Oct 15 19:01:51 2005 @@ -232,44 +232,48 @@ Convert a 16-bit integer from network to host byte order. """ - try: - return space.wrap(socket.ntohs(x)) - except socket.error, e: - raise wrap_socketerror(space, e) + return space.wrap(socket.ntohs(x)) ntohs.unwrap_spec = [ObjSpace, int] -def ntohl(space, x): +def ntohl(space, w_x): """ntohl(integer) -> integer Convert a 32-bit integer from network to host byte order. """ - try: - return space.wrap(socket.ntohl(x)) - except socket.error, e: - raise wrap_socketerror(space, e) -ntohl.unwrap_spec = [ObjSpace, int] + if space.is_true(space.isinstance(w_x, space.w_int)): + x = space.int_w(w_x) + elif space.is_true(space.isinstance(w_x, space.w_long)): + x = space.uint_w(w_x) + else: + raise OperationError(space.w_TypeError, + space.wrap("expected int/long")) + + return space.wrap(socket.ntohl(x)) +ntohl.unwrap_spec = [ObjSpace, W_Root] def htons(space, x): """htons(integer) -> integer Convert a 16-bit integer from host to network byte order. """ - try: - return space.wrap(socket.htons(x)) - except socket.error, e: - raise wrap_socketerror(space, e) + return space.wrap(socket.htons(x)) htons.unwrap_spec = [ObjSpace, int] -def htonl(space, x): +def htonl(space, w_x): """htonl(integer) -> integer Convert a 32-bit integer from host to network byte order. """ - try: - return space.wrap(socket.htonl(x)) - except socket.error, e: - raise wrap_socketerror(space, e) -htonl.unwrap_spec = [ObjSpace, int] + if space.is_true(space.isinstance(w_x, space.w_int)): + x = space.int_w(w_x) + elif space.is_true(space.isinstance(w_x, space.w_long)): + x = space.uint_w(w_x) + else: + raise OperationError(space.w_TypeError, + space.wrap("expected int/long")) + + return space.wrap(socket.htonl(x)) +htonl.unwrap_spec = [ObjSpace, W_Root] def inet_aton(space, ip): """inet_aton(string) -> packed 32-bit IP representation Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Sat Oct 15 19:01:51 2005 @@ -178,6 +178,27 @@ def setup_class(cls): cls.space = space + def test_NtoH(self): + import _socket as socket + # This just checks that htons etc. are their own inverse, + # when looking at the lower 16 or 32 bits. + sizes = {socket.htonl: 32, socket.ntohl: 32, + socket.htons: 16, socket.ntohs: 16} + for func, size in sizes.items(): + mask = (1L< Author: cfbolz Date: Sat Oct 15 19:02:11 2005 New Revision: 18651 Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py pypy/dist/pypy/rpython/l3interp/model.py pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: add branching test and op_int_is_true to l3interp Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/l3interp.py Sat Oct 15 19:02:11 2005 @@ -64,4 +64,6 @@ int2 = self.get_int(args[1]) self.set_int(result, int1 + int2) - + def op_int_is_true(self, result, args): + int1 = self.get_int(args[0]) + self.set_int(result, bool(int1)) Modified: pypy/dist/pypy/rpython/l3interp/model.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/model.py (original) +++ pypy/dist/pypy/rpython/l3interp/model.py Sat Oct 15 19:02:11 2005 @@ -102,6 +102,10 @@ self.move_int_registers = None class ReturnLink(Link): + def __init__(self, return_val=0, exitcase=None): + Link.__init__(self, None, exitcase) + if return_val != 0: + self.move_int_registers = [return_val, 0] pass class StartLink(Link): Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sat Oct 15 19:02:11 2005 @@ -14,8 +14,10 @@ #---------------------------------------------------------------------- def eval_seven(): + #def f(): + # return 3 + 4 op = model.Operation(l3interp.LLFrame.op_int_add, 0, [-1, -2]) - returnlink = model.ReturnLink(None, []) + returnlink = model.ReturnLink() block = model.Block([], model.ONE_EXIT, [returnlink]) block.operations.append(op) startlink = model.Link(block, []) @@ -26,7 +28,6 @@ interp = l3interp.LLInterpreter() return interp.eval_graph_int(graph, []) - def test_very_simple(): result = eval_seven() assert result == 7 @@ -37,9 +38,10 @@ #---------------------------------------------------------------------- def eval_eight(number): + #def f(x): + # return x + 4 op = model.Operation(l3interp.LLFrame.op_int_add, 1, [0, -1]) - returnlink = model.ReturnLink(target=None) - returnlink.move_int_registers = [1, 0] + returnlink = model.ReturnLink(return_val=1) block = model.Block([], model.ONE_EXIT, [returnlink]) block.operations.append(op) startlink = model.Link(target=block) @@ -58,3 +60,34 @@ def test_simple_translated(): fn = translate(eval_eight, [int]) assert fn(4) == 8 +#---------------------------------------------------------------------- + +def eval_branch(number): + #def f(x): + # if x: + # return 2 + # return 1 + op = model.Operation(l3interp.LLFrame.op_int_is_true, 1, [0]) + returnlink1 = model.ReturnLink(-1) + returnlink2 = model.ReturnLink(-2) + block = model.Block([], 1, [returnlink1, returnlink2]) + block.operations.append(op) + startlink = model.Link(target=block) + startlink.move_int_registers = [0, 0] + graph = model.Graph("testgraph", startlink) + graph.set_constants_int([1, 2]) + g = model.Globals() + g.graphs = [graph] + interp = l3interp.LLInterpreter() + return interp.eval_graph_int(graph, [number]) + +def test_branch(): + result = eval_branch(4) + assert result == 2 + result = eval_branch(0) + assert result == 1 + +def test_branch_translated(): + fn = translate(eval_branch, [int]) + assert fn(4) == 2 + assert fn(0) == 1 From afa at codespeak.net Sat Oct 15 19:07:18 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 19:07:18 +0200 (CEST) Subject: [pypy-svn] r18652 - pypy/dist/pypy/module/_socket Message-ID: <20051015170718.4DA7827B52@code1.codespeak.net> Author: afa Date: Sat Oct 15 19:07:17 2005 New Revision: 18652 Modified: pypy/dist/pypy/module/_socket/interp_socket.py Log: valentino, afa: better error message in socket.htonl Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sat Oct 15 19:07:17 2005 @@ -246,7 +246,8 @@ x = space.uint_w(w_x) else: raise OperationError(space.w_TypeError, - space.wrap("expected int/long")) + space.wrap("expected int/long, %s found" % + (space.type(w_x).getname(space, "?")))) return space.wrap(socket.ntohl(x)) ntohl.unwrap_spec = [ObjSpace, W_Root] @@ -270,7 +271,8 @@ x = space.uint_w(w_x) else: raise OperationError(space.w_TypeError, - space.wrap("expected int/long")) + space.wrap("expected int/long, %s found" % + (space.type(w_x).getname(space, "?")))) return space.wrap(socket.htonl(x)) htonl.unwrap_spec = [ObjSpace, W_Root] From cfbolz at codespeak.net Sat Oct 15 19:22:47 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 15 Oct 2005 19:22:47 +0200 (CEST) Subject: [pypy-svn] r18653 - in pypy/dist/pypy/rpython: . test Message-ID: <20051015172247.C031B27B52@code1.codespeak.net> Author: cfbolz Date: Sat Oct 15 19:22:45 2005 New Revision: 18653 Added: pypy/dist/pypy/rpython/test/test_ootype_llinterp.py Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/test/test_llinterp.py Log: (bert, cfbolz): extended the llinterpreter to understand some first operations of the ootype system. test. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sat Oct 15 19:22:45 2005 @@ -6,6 +6,7 @@ from pypy.rpython.rmodel import getfunctionptr from pypy.rpython.memory import lladdress from pypy.rpython.objectmodel import free_non_gc_object +from pypy.rpython.ootypesystem import ootype import math import py @@ -619,6 +620,22 @@ func = opimpls['ne'] return func(x, y) + #Operation of ootype + + def op_new(self, INST): + assert isinstance(INST, ootype.Instance) + return ootype.new(INST) + + def op_oosetfield(self, inst, name, value): + assert isinstance(inst, ootype._instance) + assert isinstance(name, str) + setattr(inst, name, value) + + def op_oogetfield(self, inst, name): + assert isinstance(inst, ootype._instance) + assert isinstance(name, str) + return getattr(inst, name) + # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help # for failing tests 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 Sat Oct 15 19:22:45 2005 @@ -19,7 +19,6 @@ def teardown_module(mod): py.log._setstate(mod.logstate) - def find_exception(exc, interp): assert isinstance(exc, LLException) import exceptions @@ -41,7 +40,8 @@ #print "%.2f secs" %(elapsed,) return res -def gengraph(func, argtypes=[], viewbefore=False, policy=None): +def gengraph(func, argtypes=[], viewbefore=False, policy=None, + type_system="lltype"): t = Translator(func) timelog("annotating", t.annotate, argtypes, policy=policy) @@ -49,7 +49,7 @@ t.annotator.simplify() t.view() global typer # we need it for find_exception - typer = RPythonTyper(t.annotator) + typer = RPythonTyper(t.annotator, type_system=type_system) timelog("rtyper-specializing", typer.specialize) #t.view() timelog("checking graphs", t.checkgraphs) @@ -57,7 +57,8 @@ _lastinterpreted = [] _tcache = {} -def get_interpreter(func, values, view=False, viewbefore=False, policy=None, someobjects=False): +def get_interpreter(func, values, view=False, viewbefore=False, policy=None, + someobjects=False, type_system="lltype"): key = (func,) + tuple([typeOf(x) for x in values])+ (someobjects,) try: (t, interp) = _tcache[key] @@ -72,7 +73,8 @@ return lltype_to_annotation(T) t, typer = gengraph(func, [annotation(x) - for x in values], viewbefore, policy) + for x in values], + viewbefore, policy, type_system=type_system) interp = LLInterpreter(t.flowgraphs, typer) _tcache[key] = (t, interp) # keep the cache small @@ -84,14 +86,15 @@ return interp def interpret(func, values, view=False, viewbefore=False, policy=None, - someobjects=False): + someobjects=False, type_system="lltype"): interp = get_interpreter(func, values, view, viewbefore, policy, - someobjects) + someobjects, type_system=type_system) return interp.eval_function(func, values) -def interpret_raises(exc, func, values, view=False, viewbefore=False, policy=None, someobjects=False): +def interpret_raises(exc, func, values, view=False, viewbefore=False, + policy=None, someobjects=False, type_system="lltype"): interp = get_interpreter(func, values, view, viewbefore, policy, - someobjects) + someobjects, type_system=type_system) info = py.test.raises(LLException, "interp.eval_function(func, values)") assert find_exception(info.value, interp) is exc, "wrong exception type" Added: pypy/dist/pypy/rpython/test/test_ootype_llinterp.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/test/test_ootype_llinterp.py Sat Oct 15 19:22:45 2005 @@ -0,0 +1,14 @@ +from pypy.rpython.ootypesystem.ootype import * +from pypy.rpython.test.test_llinterp import interpret + +def test_simple_field(): + C = Instance("test", None, {'a': (Signed, 3)}) + + def f(): + c = new(C) + c.a = 5 + return c.a + + result = interpret(f, [], type_system="ootype") + assert result == 5 + From mwh at codespeak.net Sat Oct 15 19:25:56 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 19:25:56 +0200 (CEST) Subject: [pypy-svn] r18654 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20051015172556.DB62927B52@code1.codespeak.net> Author: mwh Date: Sat Oct 15 19:25:52 2005 New Revision: 18654 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py Log: (boria, mwh) Added sanity checking to _add_methods, and a comment. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Sat Oct 15 19:25:52 2005 @@ -68,9 +68,15 @@ self._fields.update(fields) def _add_methods(self, methods): - for name in methods: + # Note to the unwary: _add_methods adds *methods* whereas + # _add_fields adds *descriptions* of fields. This is obvious + # if you are in the right state of mind (swiss?), but + # certainly not necessarily if not. + for name, method in methods.iteritems(): if self._has_field(name): raise TypeError("Can't add method %r: field already exists" % name) + if not isinstance(typeOf(method), Meth): + raise TypeError("added methods must be _meths, not %s" % type(defn)) self._methods.update(methods) def _init_instance(self, instance): From cfbolz at codespeak.net Sat Oct 15 19:27:39 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sat, 15 Oct 2005 19:27:39 +0200 (CEST) Subject: [pypy-svn] r18655 - in pypy/dist/pypy/rpython: . test Message-ID: <20051015172739.25B6827B44@code1.codespeak.net> Author: cfbolz Date: Sat Oct 15 19:27:36 2005 New Revision: 18655 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/test/test_ootype_llinterp.py Log: (bert, cfbolz): add ootype operation oosend to llinterp + test Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sat Oct 15 19:27:36 2005 @@ -635,6 +635,11 @@ assert isinstance(inst, ootype._instance) assert isinstance(name, str) return getattr(inst, name) + + def op_oosend(self, message, inst, *args): + assert isinstance(inst, ootype._instance) + assert isinstance(message, str) + return getattr(inst, message)(*args) # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help Modified: pypy/dist/pypy/rpython/test/test_ootype_llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_ootype_llinterp.py (original) +++ pypy/dist/pypy/rpython/test/test_ootype_llinterp.py Sat Oct 15 19:27:36 2005 @@ -11,4 +11,18 @@ result = interpret(f, [], type_system="ootype") assert result == 5 - + +def test_simple_method(): + C = Instance("test", None, {'a': (Signed, 3)}) + M = Meth([], Signed) + def m_(self): + return self.a + m = meth(M, _name="m", _callable=m_) + addMethods(C, {"m": m}) + + def f(): + c = new(C) + return c.m() + + result = interpret(f, [], type_system="ootype") + assert result == 3 From bert at codespeak.net Sat Oct 15 19:35:05 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Sat, 15 Oct 2005 19:35:05 +0200 (CEST) Subject: [pypy-svn] r18656 - in pypy/dist/pypy/translator/squeak: . test Message-ID: <20051015173505.9562327B56@code1.codespeak.net> Author: bert Date: Sat Oct 15 19:35:05 2005 New Revision: 18656 Modified: pypy/dist/pypy/translator/squeak/gensqueak.py pypy/dist/pypy/translator/squeak/test/test_oo.py Log: implement setfield and getfield Modified: pypy/dist/pypy/translator/squeak/gensqueak.py ============================================================================== --- pypy/dist/pypy/translator/squeak/gensqueak.py (original) +++ pypy/dist/pypy/translator/squeak/gensqueak.py Sat Oct 15 19:35:05 2005 @@ -9,8 +9,9 @@ selectormap = { 'setitem:with:': 'at:put:', 'getitem:': 'at:', - 'new': 'new', + 'new': 'new', 'sameAs': 'yourself', + 'intAdd:': '+', } def camel_case(str): @@ -39,10 +40,15 @@ if (':' in sel): parts = [] names = sel.split(':') +# assert len(names) == len(args) while args: parts.append(names.pop(0) + ': ' + args.pop(0)) return ' '.join(parts) + elif not sel[0].isalnum(): +# assert len(args) == 1 + return "%s %s" %(sel, args[0]) else: +# assert len(args) == 0 return sel @@ -151,10 +157,18 @@ def oper(op): args = [expr(arg) for arg in op.args] if op.opname == "oosend": - name = args[0] + name = op.args[0].value receiver = args[1] args = args[2:] self.note_meth(op.args[1].concretetype, name) + elif op.opname == "oogetfield": + receiver = args[0] + name = op.args[1].value + args = args[2:] + elif op.opname == "oosetfield": + receiver = args[0] + name = op.args[1].value + args = args[2:] else: name = op.opname receiver = args[0] @@ -258,7 +272,7 @@ return str(i) def nameof_str(self, s): - return s + return "'s'" def nameof_function(self, func): #XXX this should actually be a StaticMeth Modified: pypy/dist/pypy/translator/squeak/test/test_oo.py ============================================================================== --- pypy/dist/pypy/translator/squeak/test/test_oo.py (original) +++ pypy/dist/pypy/translator/squeak/test/test_oo.py Sat Oct 15 19:35:05 2005 @@ -12,7 +12,7 @@ t.specialize(type_system="ootype") t.simplify() if view: - t.view() + t.viewcg() GenSqueak(udir, t) @@ -30,8 +30,17 @@ c = new(C) return c.m(5) +def f_fields(): + c = new(C) + x = c.a + 1 + c.a = x + return x + def test_simple_new(): build_sqfunc(f_new) def test_simple_meth(): - build_sqfunc(f_meth, view=False) + build_sqfunc(f_meth) + +def test_simple_fields(): + build_sqfunc(f_fields, view=False) From dialtone at codespeak.net Sat Oct 15 19:43:22 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Sat, 15 Oct 2005 19:43:22 +0200 (CEST) Subject: [pypy-svn] r18657 - in pypy/dist/pypy: module/_socket/rpython module/_socket/rpython/test translator/c/src Message-ID: <20051015174322.A274227B52@code1.codespeak.net> Author: dialtone Date: Sat Oct 15 19:43:19 2005 New Revision: 18657 Added: pypy/dist/pypy/module/_socket/rpython/ pypy/dist/pypy/module/_socket/rpython/__init__.py pypy/dist/pypy/module/_socket/rpython/exttable.py pypy/dist/pypy/module/_socket/rpython/ll__socket.py pypy/dist/pypy/module/_socket/rpython/test/ pypy/dist/pypy/module/_socket/rpython/test/__init__.py pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py pypy/dist/pypy/translator/c/src/ll__socket.h Log: starting translation work on socket module Added: pypy/dist/pypy/module/_socket/rpython/__init__.py ============================================================================== Added: pypy/dist/pypy/module/_socket/rpython/exttable.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/rpython/exttable.py Sat Oct 15 19:43:19 2005 @@ -0,0 +1,13 @@ +""" +Annotation support for interp-level socket objects. +""" + +import _socket +from pypy.rpython.extfunctable import declare + +module = 'pypy.module._socket.rpython.ll__socket' + +# ____________________________________________________________ +# Built-in functions needed in the rtyper + +declare(_socket.ntohs, int, '%s/ntohs' % module) Added: pypy/dist/pypy/module/_socket/rpython/ll__socket.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Sat Oct 15 19:43:19 2005 @@ -0,0 +1,5 @@ +import _socket + +def ll__socket_ntohs(htons): + return _socket.ntohs(htons) +ll__socket_ntohs.suggested_primitive = True Added: pypy/dist/pypy/module/_socket/rpython/test/__init__.py ============================================================================== Added: pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py Sat Oct 15 19:43:19 2005 @@ -0,0 +1,13 @@ + +import _socket +import pypy.module._socket.rpython.exttable +from pypy.module._socket.rpython.ll__socket import * +from pypy.translator.annrpython import RPythonAnnotator +from pypy.rpython.test.test_llinterp import interpret + +def test_ntohs(): + def fn(): + return _socket.ntohs(1) + a = RPythonAnnotator() + res = interpret(fn, []) + assert res == _socket.ntohs(1) Added: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Sat Oct 15 19:43:19 2005 @@ -0,0 +1,21 @@ + +#ifdef MS_WINDOWS + #include + #include +#else + #include +#endif + +int LL__socket_ntohs(int htons); + + +#ifndef PYPY_NOT_MAIN_FILE + +int LL__socket_ntohs(int htons) +{ + + return (int)ntohs((short) htons); + +} + +#endif From mwh at codespeak.net Sat Oct 15 19:48:40 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 19:48:40 +0200 (CEST) Subject: [pypy-svn] r18658 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051015174840.0D85227B52@code1.codespeak.net> Author: mwh Date: Sat Oct 15 19:48:38 2005 New Revision: 18658 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Log: (boria, mwh) fix bug in ootype._instance.__setattr__ when assigning to a field present in a superclass. added test. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Sat Oct 15 19:48:38 2005 @@ -96,9 +96,16 @@ return self._superclass._has_field(name) - def _check_field(self, name): - if not self._has_field(name): - raise TypeError("No field named %r" % name) + def _field_type(self, name): + try: + return self._fields[name][0] + except KeyError: + if self._superclass is None: + raise TypeError("No field names %r" % name) + + return self._superclass._field_type(name) + + _check_field = _field_type def _lookup(self, meth_name): meth = self._methods.get(meth_name) @@ -147,8 +154,8 @@ def __setattr__(self, name, value): self.__getattr__(name) - if self._TYPE._fields[name][0] != typeOf(value): - raise TypeError("Expected type %r" % self._TYPE._fields[name][0]) + if self._TYPE._field_type(name) != typeOf(value): + raise TypeError("Expected type %r" % self._TYPE._field_type(name)) self.__dict__[name] = value Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Sat Oct 15 19:48:38 2005 @@ -22,6 +22,16 @@ i.a = 3 assert i.a == 3 +def test_assign_super_attr(): + C = Instance("test", None, {"a": (Signed, 3)}) + D = Instance("test2", C, {}) + + d = new(D) + + d.a = 1 + + assert d.a == 1 + def test_runtime_instanciation(): I = Instance("test", None, {"a": Signed}) c = runtimeClass(I) From afa at codespeak.net Sat Oct 15 19:58:22 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 15 Oct 2005 19:58:22 +0200 (CEST) Subject: [pypy-svn] r18659 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051015175822.2379F27B52@code1.codespeak.net> Author: afa Date: Sat Oct 15 19:58:20 2005 New Revision: 18659 Modified: pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/test/test_extfunc.py Log: valentino, afa: more progress on socket module translation Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Sat Oct 15 19:58:20 2005 @@ -7,6 +7,7 @@ from pypy.rpython.module import ll_os, ll_time, ll_math, ll_strtod from pypy.rpython.module import ll_stackless, ll_stack from pypy.module.thread.rpython import ll_thread +from pypy.module._socket.rpython import ll__socket # table of functions hand-written in src/ll_*.h @@ -53,6 +54,7 @@ ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', ll_stack.ll_stack_unwind: 'LL_stack_unwind', ll_stack.ll_stack_too_big: 'LL_stack_too_big', + ll__socket.ll__socket_ntohs: 'LL__socket_ntohs', } #______________________________________________________ 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 Sat Oct 15 19:58:20 2005 @@ -497,3 +497,12 @@ assert _real_getenv('ABCDEF') is None f() assert _real_getenv('ABCDEF') is None + +def INPROGRESStest_socket(): + import _socket + import pypy.module._socket.rpython.exttable # for declare()/declaretype() + def fn(): + print _socket.ntohs(123) + f = compile(fn, []) + f() + From mwh at codespeak.net Sat Oct 15 20:00:04 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 20:00:04 +0200 (CEST) Subject: [pypy-svn] r18660 - pypy/dist/pypy/rpython Message-ID: <20051015180004.7583927B49@code1.codespeak.net> Author: mwh Date: Sat Oct 15 20:00:02 2005 New Revision: 18660 Modified: pypy/dist/pypy/rpython/llinterp.py Log: don't refer to f._obj in LLFrame.op_direct_call, call self.llinterpreter.typer.type_system.deref(f) instead. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sat Oct 15 20:00:02 2005 @@ -295,14 +295,15 @@ self.op_direct_call(write_barrier, *args) def op_direct_call(self, f, *args): - has_callable = getattr(f._obj, '_callable', None) is not None - if has_callable and getattr(f._obj._callable, 'suggested_primitive', False): + obj = self.llinterpreter.typer.type_system.deref(f) + has_callable = getattr(obj, '_callable', None) is not None + if has_callable and getattr(obj._callable, 'suggested_primitive', False): return self.invoke_callable_with_pyexceptions(f, *args) - if hasattr(f._obj, 'graph'): - graph = f._obj.graph + if hasattr(obj, 'graph'): + graph = obj.graph else: try: - graph = self.llinterpreter.getgraph(f._obj._callable) + graph = self.llinterpreter.getgraph(obj._callable) except KeyError: assert has_callable, "don't know how to execute %r" % f return self.invoke_callable_with_pyexceptions(f, *args) From mwh at codespeak.net Sat Oct 15 20:00:56 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sat, 15 Oct 2005 20:00:56 +0200 (CEST) Subject: [pypy-svn] r18661 - pypy/dist/pypy/rpython/ootypesystem/test Message-ID: <20051015180056.D8B4A27B56@code1.codespeak.net> Author: mwh Date: Sat Oct 15 20:00:55 2005 New Revision: 18661 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: use this llinterpreter in our tests, and an inprogress test. Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sat Oct 15 20:00:55 2005 @@ -1,6 +1,8 @@ from pypy.translator.translator import Translator from pypy.rpython import lltype from pypy.rpython.ootypesystem import ootype +from pypy.rpython.test.test_llinterp import interpret +import py def specialize(f, input_types, viewBefore=False, viewAfter=False): t = Translator(f) @@ -28,7 +30,8 @@ def test_simple(): def f(a, b): return a + b - specialize(f, [int, int]) + result = interpret(f, [1, 2], type_system='ootype') + assert result == 3 def test_simple_call(): def f(a, b): @@ -36,7 +39,8 @@ def g(): return f(5, 3) - specialize(g, []) + result = interpret(g, [], type_system='ootype') + assert result == 8 # Adjusted from test_rclass.py class EmptyBase(object): @@ -46,7 +50,8 @@ def dummyfn(): x = EmptyBase() return x - specialize(dummyfn, []) + result = interpret(dummyfn, [], type_system='ootype') + assert isinstance(ootype.typeOf(result), ootype.Instance) def test_instance_attribute(): @@ -54,7 +59,8 @@ x = EmptyBase() x.a = 1 return x.a - specialize(dummyfn, []) + result = interpret(dummyfn, [], type_system='ootype') + assert result == 1 class Subclass(EmptyBase): pass @@ -67,6 +73,16 @@ y.a = 2 y.b = 3 return x.a + y.a + y.b - specialize(dummyfn, []) - + result = interpret(dummyfn, [], type_system='ootype') + assert result == 1 + 2 + 3 + +class HasAMethod(object): + def f(self): + return 1 +def test_method(): + py.test.skip('in progress') + def dummyfn(): + inst = HasAMethod() + return inst.f() + specialize(dummyfn, [])#, viewBefore=True) From bert at codespeak.net Sat Oct 15 20:01:44 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Sat, 15 Oct 2005 20:01:44 +0200 (CEST) Subject: [pypy-svn] r18662 - in pypy/dist/pypy: rpython rpython/ootypesystem translator/squeak translator/squeak/test Message-ID: <20051015180144.9F4AA27B58@code1.codespeak.net> Author: bert Date: Sat Oct 15 20:01:44 2005 New Revision: 18662 Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/translator/squeak/gensqueak.py pypy/dist/pypy/translator/squeak/test/test_oo.py Log: implement classof and runtimenew Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rootype.py Sat Oct 15 20:01:44 2005 @@ -1,8 +1,14 @@ from pypy.annotation import model as annmodel from pypy.rpython.rmodel import Repr -from pypy.rpython.ootypesystem.ootype import Void +from pypy.rpython.ootypesystem.ootype import Void, Class from pypy.annotation.pairtype import pairtype +class __extend__(annmodel.SomeOOClass): + def rtyper_makerepr(self, rtyper): + return ooclass_repr + def rtyper_makekey(self): + return self.__class__, + class __extend__(annmodel.SomeOOInstance): def rtyper_makerepr(self, rtyper): return OOInstanceRepr(self.ootype) @@ -15,6 +21,10 @@ def rtyper_makekey(self): return self.__class__, self.ootype, self.name +class OOClassRepr(Repr): + lowleveltype = Class +ooclass_repr = OOClassRepr() + class OOInstanceRepr(Repr): def __init__(self, ootype): self.lowleveltype = ootype Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Sat Oct 15 20:01:44 2005 @@ -270,6 +270,16 @@ return hop.genop('new', vlist, resulttype = hop.r_result.lowleveltype) +def rtype_classof(hop): + assert isinstance(hop.args_s[0], annmodel.SomeOOInstance) + return hop.genop('classof', hop.args_v, + resulttype = ootype.Class) + +def rtype_runtimenew(hop): + assert isinstance(hop.args_s[0], annmodel.SomeOOClass) + return hop.genop('runtimenew', hop.args_v, + resulttype = hop.r_result.lowleveltype) + BUILTIN_TYPER[lltype.malloc] = rtype_malloc BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer BUILTIN_TYPER[lltype.cast_ptr_to_int] = rtype_cast_ptr_to_int @@ -284,6 +294,8 @@ BUILTIN_TYPER[objectmodel.hlinvoke] = rtype_hlinvoke BUILTIN_TYPER[ootype.new] = rtype_new +BUILTIN_TYPER[ootype.classof] = rtype_classof +BUILTIN_TYPER[ootype.runtimenew] = rtype_runtimenew from pypy.rpython import extfunctable Modified: pypy/dist/pypy/translator/squeak/gensqueak.py ============================================================================== --- pypy/dist/pypy/translator/squeak/gensqueak.py (original) +++ pypy/dist/pypy/translator/squeak/gensqueak.py Sat Oct 15 20:01:44 2005 @@ -10,6 +10,8 @@ 'setitem:with:': 'at:put:', 'getitem:': 'at:', 'new': 'new', + 'runtimenew': 'new', + 'classof': 'class', 'sameAs': 'yourself', 'intAdd:': '+', } Modified: pypy/dist/pypy/translator/squeak/test/test_oo.py ============================================================================== --- pypy/dist/pypy/translator/squeak/test/test_oo.py (original) +++ pypy/dist/pypy/translator/squeak/test/test_oo.py Sat Oct 15 20:01:44 2005 @@ -23,24 +23,35 @@ m = meth(M, _name="m", _callable=m_) addMethods(C, {"m": m}) -def f_new(): - return new(C) - -def f_meth(): - c = new(C) - return c.m(5) - -def f_fields(): - c = new(C) - x = c.a + 1 - c.a = x - return x - def test_simple_new(): + def f_new(): + return new(C) build_sqfunc(f_new) def test_simple_meth(): + def f_meth(): + c = new(C) + return c.m(5) build_sqfunc(f_meth) def test_simple_fields(): + def f_fields(): + c = new(C) + x = c.a + 1 + c.a = x + return x build_sqfunc(f_fields, view=False) + +def test_simple_classof(): + def f_classof(): + c = new(C) + return classof(c) + build_sqfunc(f_classof) + +def test_simple_runtimenew(): + def f_runtimenew(): + c = new(C) + m = classof(c) + i = runtimenew(m) + return i.a + build_sqfunc(f_runtimenew) From ericvrp at codespeak.net Sat Oct 15 23:06:36 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 15 Oct 2005 23:06:36 +0200 (CEST) Subject: [pypy-svn] r18663 - pypy/dist/pypy/translator/js Message-ID: <20051015210636.DAB5527B3E@code1.codespeak.net> Author: ericvrp Date: Sat Oct 15 23:06:35 2005 New Revision: 18663 Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/exception.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/node.py pypy/dist/pypy/translator/js/opwriter.py Log: * cleaning up (somewhat) exception policy * adapt to js syntax (somwhat) * replace dot with space in function-names ( A.__init__ ) Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Sat Oct 15 23:06:35 2005 @@ -13,6 +13,9 @@ self.js = js self._skip_closeblock = False + def skip_closeblock(self, flag=True): + self._skip_closeblock = flag + def append(self, line, indentation_level=4): if indentation_level: s = self.tabstring * indentation_level @@ -43,7 +46,7 @@ def closeblock(self): if not self._skip_closeblock: self.append('break') - self._skip_closeblock = False + self.skip_closeblock(False) def globalinstance(self, name, typeanddata): #self.append('%s = %s' % (name, typeanddata[1:].split('{')[1][:-1]), 0) @@ -98,7 +101,7 @@ def br_uncond(self, block, exit): self._phi(block, exit) self._goto_block(block) - self._skip_closeblock = True + self.skip_closeblock() def br(self, cond, block_false, exit_false, block_true, exit_true): self.append('if (%s) {' % cond) @@ -108,7 +111,7 @@ self._phi(block_false, exit_false, 5) self._goto_block(block_false, 5) self.append('}') - self._skip_closeblock = True + self.skip_closeblock() def switch(self, intty, cond, defaultdest, value_label): labels = '' @@ -147,7 +150,7 @@ self.append("return") else: self.append("return " + ref) - self._skip_closeblock = True + self.skip_closeblock() def binaryop(self, name, targetvar, type_, ref1, ref2): self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) Modified: pypy/dist/pypy/translator/js/exception.py ============================================================================== --- pypy/dist/pypy/translator/js/exception.py (original) +++ pypy/dist/pypy/translator/js/exception.py Sat Oct 15 23:06:35 2005 @@ -1,26 +1,4 @@ class ExceptionPolicy: - RINGBUGGER_SIZE = 8192 - RINGBUFFER_ENTRY_MAXSIZE = 16 - RINGBUGGER_OVERSIZE = RINGBUGGER_SIZE + RINGBUFFER_ENTRY_MAXSIZE - RINGBUFFER_LLVMCODE = ''' -sbyte* %%malloc_exception(uint %%nbytes) { - %%cond = setle uint %%nbytes, %d - br bool %%cond, label %%then, label %%else - -then: - %%tmp.3 = load uint* %%exception_ringbuffer_index - %%tmp.4 = getelementptr [%d x sbyte]* %%exception_ringbuffer, int 0, uint %%tmp.3 - %%tmp.6 = add uint %%tmp.3, %%nbytes - %%tmp.7 = and uint %%tmp.6, %d - store uint %%tmp.7, uint* %%exception_ringbuffer_index - ret sbyte* %%tmp.4 - -else: - %%tmp.8 = call sbyte* %%GC_malloc(uint %%nbytes) - ret sbyte* %%tmp.8 -} -''' % (RINGBUFFER_ENTRY_MAXSIZE, RINGBUGGER_OVERSIZE, RINGBUGGER_SIZE-1) - def __init__(self): raise Exception, 'ExceptionPolicy should not be used directly' @@ -71,32 +49,6 @@ def __init__(self): pass - def llvmcode(self, entrynode): - returntype, entrypointname = entrynode.getdecl().split('%', 1) - noresult = self._noresult(returntype) - return ''' -%(returntype)s%%__entrypoint__%(entrypointname)s { - %%result = invoke %(returntype)s%%%(entrypointname)s to label %%no_exception except label %%exception - -no_exception: - store %%RPYTHON_EXCEPTION_VTABLE* null, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type - ret %(returntype)s %%result - -exception: - ret %(noresult)s -} - -int %%__entrypoint__raised_LLVMException() { - %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type - %%result = cast %%RPYTHON_EXCEPTION_VTABLE* %%tmp to int - ret int %%result -} - -void %%unwind() { - unwind -} -''' % locals() + self.RINGBUFFER_LLVMCODE - def invoke(self, codewriter, targetvar, returntype, functionref, args, label, except_label): labels = 'to label %%%s except label %%%s' % (label, except_label) if returntype == 'void': @@ -113,7 +65,7 @@ for i, arg in enumerate(inputargs): names = db.repr_arg_multi([link.args[i] for link in entrylinks]) for name in names: #These tests-by-name are a bit yikes, but I don't see a better way right now - if not name.startswith('%last_exception_') and not name.startswith('%last_exc_value_'): + if not name.startswith('last_exception_') and not name.startswith('last_exc_value_'): is_raise_new = True return is_raise_new @@ -124,33 +76,33 @@ graph = funcnode.graph if self._is_raise_new_exception(db, graph, block): - funcnode.write_block_phi_nodes(codewriter, block) - inputargs = db.repr_arg_multi(block.inputargs) inputargtypes = db.repr_arg_type_multi(block.inputargs) - codewriter.store(inputargtypes[0], inputargs[0], '%last_exception_type') - codewriter.store(inputargtypes[1], inputargs[1], '%last_exception_value') + codewriter.store('last_exception_type' , [], inputargs[0]) + codewriter.store('last_exception_value', [], inputargs[1]) else: codewriter.comment('reraise last exception') #Reraising last_exception. #Which is already stored in the global variables. #So nothing needs to happen here! - codewriter.llvm('unwind') + codewriter.append('throw "Pypy exception"') + codewriter.skip_closeblock() def fetch_exceptions(self, codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value): for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: codewriter.label(label) if last_exc_type_var: - codewriter.load(last_exc_type_var, lltype_of_exception_type, '%last_exception_type') + codewriter.load(last_exc_type_var, lltype_of_exception_type, 'last_exception_type') if last_exc_value_var: - codewriter.load(last_exc_value_var, lltype_of_exception_value, '%last_exception_value') + codewriter.load(last_exc_value_var, lltype_of_exception_value, 'last_exception_value') codewriter.br_uncond(target) def reraise(self, funcnode, codewriter): codewriter.comment('reraise when exception is not caught') - codewriter.llvm('unwind') + codewriter.append('throw "Pypy exception"') + codewriter.skip_closeblock() def llc_options(self): return '-enable-correct-eh-support' @@ -160,35 +112,6 @@ def __init__(self): self.invoke_count = 0 - def llvmcode(self, entrynode): - returntype, entrypointname = entrynode.getdecl().split('%', 1) - noresult = self._noresult(returntype) - return ''' -%(returntype)s%%__entrypoint__%(entrypointname)s { - store %%RPYTHON_EXCEPTION_VTABLE* null, %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type - %%result = call %(returntype)s%%%(entrypointname)s - %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type - %%exc = seteq %%RPYTHON_EXCEPTION_VTABLE* %%tmp, null - br bool %%exc, label %%no_exception, label %%exception - -no_exception: - ret %(returntype)s %%result - -exception: - ret %(noresult)s -} - -int %%__entrypoint__raised_LLVMException() { - %%tmp = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type - %%result = cast %%RPYTHON_EXCEPTION_VTABLE* %%tmp to int - ret int %%result -} - -void %%unwind() { - ret void -} -''' % locals() + self.RINGBUFFER_LLVMCODE - def transform(self, translator, graph=None): from pypy.translator.llvm.backendopt.exception import create_exception_handling if graph: @@ -207,7 +130,7 @@ tmp = '%%invoke.tmp.%d' % self.invoke_count exc = '%%invoke.exc.%d' % self.invoke_count self.invoke_count += 1 - codewriter.llvm('%(tmp)s = load %%RPYTHON_EXCEPTION_VTABLE** %%last_exception_type' % locals()) + codewriter.llvm('%(tmp)s = load %%RPYTHON_EXCEPTION_VTABLE** last_exception_type' % locals()) codewriter.llvm('%(exc)s = seteq %%RPYTHON_EXCEPTION_VTABLE* %(tmp)s, null' % locals()) codewriter.llvm('br bool %(exc)s, label %%%(label)s, label %%%(except_label)s' % locals()) @@ -221,19 +144,19 @@ inputargs = funcnode.db.repr_arg_multi(block.inputargs) inputargtypes = funcnode.db.repr_arg_type_multi(block.inputargs) - codewriter.store(inputargtypes[0], inputargs[0], '%last_exception_type') - codewriter.store(inputargtypes[1], inputargs[1], '%last_exception_value') + codewriter.store(inputargtypes[0], inputargs[0], 'last_exception_type') + codewriter.store(inputargtypes[1], inputargs[1], 'last_exception_value') codewriter.llvm('ret ' + noresult) def fetch_exceptions(self, codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value): for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: codewriter.label(label) if last_exc_type_var: - codewriter.load(last_exc_type_var, lltype_of_exception_type, '%last_exception_type') + codewriter.load(last_exc_type_var, lltype_of_exception_type, 'last_exception_type') if last_exc_value_var: - codewriter.load(last_exc_value_var, lltype_of_exception_value, '%last_exception_value') - codewriter.store(lltype_of_exception_type , 'null', '%last_exception_type') - codewriter.store(lltype_of_exception_value, 'null', '%last_exception_value') + codewriter.load(last_exc_value_var, lltype_of_exception_value, 'last_exception_value') + codewriter.store(lltype_of_exception_type , 'null', 'last_exception_type') + codewriter.store(lltype_of_exception_value, 'null', 'last_exception_value') codewriter.br_uncond(target) def reraise(self, funcnode, codewriter): Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Sat Oct 15 23:06:35 2005 @@ -143,6 +143,7 @@ #codewriter.append(self.wrappercode, 0) codewriter.newline() codewriter.comment("EOF", 0) + f.close() log('Written:', self.filename) return self.filename Modified: pypy/dist/pypy/translator/js/node.py ============================================================================== --- pypy/dist/pypy/translator/js/node.py (original) +++ pypy/dist/pypy/translator/js/node.py Sat Oct 15 23:06:35 2005 @@ -15,6 +15,7 @@ " helper for creating names" if " " in name or "<" in name: name = '"%s"' % name + name = name.replace('.', '_') global _nodename_count if name in _nodename_count: Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Sat Oct 15 23:06:35 2005 @@ -295,7 +295,7 @@ none_label = self.node.blockindex[link.target] block_label = self.node.blockindex[self.block] - exc_label = block_label + '_exception_handling' + exc_label = 10000 + block_label #_exception_label #if self.db.is_function_ptr(op.result): #use longhand form # returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) @@ -303,11 +303,12 @@ argtypes, none_label, exc_label) e = self.db.translator.rtyper.getexceptiondata() - ll_exception_match = 'pypy_' + e.ll_exception_match.__name__ - lltype_of_exception_type = ('structtype.' + + pypy_prefix = '' #pypy_ + ll_exception_match = pypy_prefix + e.ll_exception_match.__name__ + lltype_of_exception_type = ('structtype_' + e.lltype_of_exception_type.TO.__name__ + '*') - lltype_of_exception_value = ('structtype.' + + lltype_of_exception_value = ('structtype_' + e.lltype_of_exception_value.TO.__name__ + '*') @@ -321,7 +322,8 @@ etype = self.db.obj2node[link.llexitcase._obj] current_exception_type = etype.get_ref() target = self.node.blockindex[link.target] - exc_found_label = block_label + '_exception_found_branchto_' + target + #exc_found_label = block_label + '_exception_found_branchto_' + target + exc_found_label = '%d_exception_found_branchto_%d' % (block_label, target) last_exc_type_var, last_exc_value_var = None, None for p in self.node.get_phi_data(link.target): From ericvrp at codespeak.net Sat Oct 15 23:22:04 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sat, 15 Oct 2005 23:22:04 +0200 (CEST) Subject: [pypy-svn] r18664 - pypy/dist/pypy/translator/js Message-ID: <20051015212204.4BE0E27B43@code1.codespeak.net> Author: ericvrp Date: Sat Oct 15 23:22:03 2005 New Revision: 18664 Modified: pypy/dist/pypy/translator/js/exception.py Log: fix load/store of exception and return statements in case of unwind. (not finished: exception tests not passing yet) Modified: pypy/dist/pypy/translator/js/exception.py ============================================================================== --- pypy/dist/pypy/translator/js/exception.py (original) +++ pypy/dist/pypy/translator/js/exception.py Sat Oct 15 23:22:03 2005 @@ -5,24 +5,6 @@ def transform(self, translator, graph=None): return - def _noresult(self, returntype): - r = returntype.strip() - if r == 'void': - return 'void' - elif r == 'bool': - return 'bool false' - elif r in 'float double'.split(): - return r + ' 0.0' - elif r in 'ubyte sbyte ushort short uint int ulong long'.split(): - return r + ' 0' - return r + ' null' - - def _nonoderesult(self, node): - decl = node.getdecl() - returntype, name = decl.split(' ', 1) - noresult = self._noresult(returntype) - return noresult - def new(exceptionpolicy=None): #factory exceptionpolicy = exceptionpolicy or 'invokeunwind' if exceptionpolicy == 'invokeunwind': @@ -94,9 +76,9 @@ for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: codewriter.label(label) if last_exc_type_var: - codewriter.load(last_exc_type_var, lltype_of_exception_type, 'last_exception_type') + codewriter.load(last_exc_type_var , 'last_exception_type' , []) if last_exc_value_var: - codewriter.load(last_exc_value_var, lltype_of_exception_value, 'last_exception_value') + codewriter.load(last_exc_value_var, 'last_exception_value', []) codewriter.br_uncond(target) def reraise(self, funcnode, codewriter): @@ -123,8 +105,7 @@ def invoke(self, codewriter, targetvar, returntype, functionref, args, label, except_label): if returntype == 'void': - if functionref != '%keepalive': #XXX I think keepalive should not be the last operation here! - codewriter.append('call void %s(%s)' % (functionref, args)) + codewriter.append('call void %s(%s)' % (functionref, args)) else: codewriter.llvm('%s = call %s %s(%s)' % (targetvar, returntype, functionref, args)) tmp = '%%invoke.tmp.%d' % self.invoke_count @@ -137,31 +118,29 @@ def write_exceptblock(self, funcnode, codewriter, block): assert len(block.inputargs) == 2 - noresult = self._nonoderesult(funcnode) - funcnode.write_block_phi_nodes(codewriter, block) inputargs = funcnode.db.repr_arg_multi(block.inputargs) inputargtypes = funcnode.db.repr_arg_type_multi(block.inputargs) - codewriter.store(inputargtypes[0], inputargs[0], 'last_exception_type') - codewriter.store(inputargtypes[1], inputargs[1], 'last_exception_value') - codewriter.llvm('ret ' + noresult) + codewriter.store('last_exception_type' , [], inputargs[0]) + codewriter.store('last_exception_value', [], inputargs[1]) + codewriter.ret('void', '') def fetch_exceptions(self, codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value): for label, target, last_exc_type_var, last_exc_value_var in exc_found_labels: codewriter.label(label) if last_exc_type_var: - codewriter.load(last_exc_type_var, lltype_of_exception_type, 'last_exception_type') + codewriter.load(last_exc_type_var , 'last_exception_type' , []) if last_exc_value_var: - codewriter.load(last_exc_value_var, lltype_of_exception_value, 'last_exception_value') - codewriter.store(lltype_of_exception_type , 'null', 'last_exception_type') - codewriter.store(lltype_of_exception_value, 'null', 'last_exception_value') + codewriter.load(last_exc_value_var, 'last_exception_value', []) + codewriter.store('last_exception_type' , [], 'null') + codewriter.store('last_exception_value', [], 'null') codewriter.br_uncond(target) + codewriter.skip_closeblock() def reraise(self, funcnode, codewriter): - noresult = self._nonoderesult(funcnode) - codewriter.llvm('ret ' + noresult) + codewriter.ret('void', '') def llc_options(self): return '' From arigo at codespeak.net Sun Oct 16 10:32:10 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 16 Oct 2005 10:32:10 +0200 (CEST) Subject: [pypy-svn] r18666 - pypy/dist/pypy/translator/c/test Message-ID: <20051016083210.53E6027B43@code1.codespeak.net> Author: arigo Date: Sun Oct 16 10:32:09 2005 New Revision: 18666 Modified: pypy/dist/pypy/translator/c/test/test_typed.py Log: Forgot to fix the test to use math.fmod() instead of %. 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 Sun Oct 16 10:32:09 2005 @@ -248,9 +248,10 @@ # floats def test_float_operations(self): + import math def func(x=float, y=float): z = x + y / 2.1 * x - z = z % 60.0 + z = math.fmod(z, 60.0) z = pow(z, 2) z = -z return int(z) From arigo at codespeak.net Sun Oct 16 10:32:49 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 16 Oct 2005 10:32:49 +0200 (CEST) Subject: [pypy-svn] r18667 - pypy/dist/pypy/translator/c/src Message-ID: <20051016083249.883CA27B43@code1.codespeak.net> Author: arigo Date: Sun Oct 16 10:32:48 2005 New Revision: 18667 Modified: pypy/dist/pypy/translator/c/src/exception.h pypy/dist/pypy/translator/c/src/g_include.h Log: Raise simple exceptions via a function instead of a macro (convenient place to set a breakpoint in the debugger). 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 Sun Oct 16 10:32:48 2005 @@ -34,19 +34,37 @@ #define RPyMatchException(etype) RPYTHON_EXCEPTION_MATCH(rpython_exc_type, \ (RPYTHON_EXCEPTION_VTABLE) etype) -#ifndef PYPY_STANDALONE - /* prototypes */ +#define RPyRaiseSimpleException(exc, msg) _RPyRaiseSimpleException(R##exc) +void _RPyRaiseSimpleException(RPYTHON_EXCEPTION rexc); + +#ifndef PYPY_STANDALONE void RPyConvertExceptionFromCPython(void); void _RPyConvertExceptionToCPython(void); +#define RPyConvertExceptionToCPython(vanishing) \ + _RPyConvertExceptionToCPython(); \ + vanishing = rpython_exc_value; \ + rpython_exc_type = NULL; \ + rpython_exc_value = NULL +#endif /* implementations */ #ifndef PYPY_NOT_MAIN_FILE +void _RPyRaiseSimpleException(RPYTHON_EXCEPTION rexc) +{ + /* XXX 1. uses officially bad fishing */ + /* XXX 2. msg is ignored */ + rpython_exc_type = rexc->o_typeptr; + rpython_exc_value = rexc; + PUSH_ALIVE(rpython_exc_value); +} + +#ifndef PYPY_STANDALONE void RPyConvertExceptionFromCPython(void) { /* convert the CPython exception to an RPython one */ @@ -77,24 +95,11 @@ PyErr_SetString(RPythonError, clsname); } } +#endif /* !PYPY_STANDALONE */ #endif /* PYPY_NOT_MAIN_FILE */ -#define RPyConvertExceptionToCPython(vanishing) \ - _RPyConvertExceptionToCPython(); \ - vanishing = rpython_exc_value; \ - rpython_exc_type = NULL; \ - rpython_exc_value = NULL - -#endif /* !PYPY_STANDALONE */ - -#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); \ - PUSH_ALIVE(rpython_exc_value) /******************************************************************/ #else /* non-RPython version of exceptions, using CPython 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 Sun Oct 16 10:32:48 2005 @@ -14,6 +14,7 @@ # include "src/standalone.h" #endif +#include "src/mem.h" #include "src/exception.h" #include "src/trace.h" #include "src/support.h" @@ -22,7 +23,6 @@ # include "src/module.h" #endif -#include "src/mem.h" #include "src/int.h" #include "src/char.h" #include "src/unichar.h" From dialtone at codespeak.net Sun Oct 16 10:48:44 2005 From: dialtone at codespeak.net (dialtone at codespeak.net) Date: Sun, 16 Oct 2005 10:48:44 +0200 (CEST) Subject: [pypy-svn] r18668 - in pypy/dist/pypy: doc/tool interpreter/pyparser/test module/_socket module/_socket/rpython module/_socket/rpython/test module/_socket/test rpython/l3interp rpython/l3interp/test rpython/module rpython/ootypesystem/test rpython/test translator/asm/ppc translator/c translator/c/src translator/c/test translator/goal/win32 translator/js translator/js/test translator/llvm/backendopt translator/test translator/tool Message-ID: <20051016084844.4DA9127B43@code1.codespeak.net> Author: dialtone Date: Sun Oct 16 10:48:23 2005 New Revision: 18668 Modified: pypy/dist/pypy/doc/tool/mydot.py (props changed) pypy/dist/pypy/interpreter/pyparser/test/stdlib_testall.py (props changed) pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/rpython/ (props changed) pypy/dist/pypy/module/_socket/rpython/__init__.py (props changed) pypy/dist/pypy/module/_socket/rpython/exttable.py (contents, props changed) pypy/dist/pypy/module/_socket/rpython/ll__socket.py (contents, props changed) pypy/dist/pypy/module/_socket/rpython/test/ (props changed) pypy/dist/pypy/module/_socket/rpython/test/__init__.py (props changed) pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py (props changed) pypy/dist/pypy/module/_socket/test/test_socket2.py pypy/dist/pypy/rpython/l3interp/ (props changed) pypy/dist/pypy/rpython/l3interp/l3interp.py (props changed) pypy/dist/pypy/rpython/l3interp/model.py (props changed) pypy/dist/pypy/rpython/l3interp/test/ (props changed) pypy/dist/pypy/rpython/l3interp/test/__init__.py (props changed) pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (props changed) pypy/dist/pypy/rpython/module/ll_stack.py (props changed) pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py (props changed) pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (props changed) pypy/dist/pypy/rpython/test/test_ootype_llinterp.py (props changed) pypy/dist/pypy/translator/asm/ppc/ (props changed) pypy/dist/pypy/translator/asm/ppc/__init__.py (props changed) pypy/dist/pypy/translator/asm/ppc/codegen.py (props changed) pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/g_include.h pypy/dist/pypy/translator/c/src/ll__socket.h pypy/dist/pypy/translator/c/test/test_extfunc.py pypy/dist/pypy/translator/goal/win32/ (props changed) pypy/dist/pypy/translator/js/ (props changed) pypy/dist/pypy/translator/js/test/ (props changed) pypy/dist/pypy/translator/llvm/backendopt/support.py (props changed) pypy/dist/pypy/translator/test/test_simplify.py (props changed) pypy/dist/pypy/translator/test/test_unsimplify.py (props changed) pypy/dist/pypy/translator/tool/pdbplus.py (props changed) pypy/dist/pypy/translator/tool/util.py (props changed) Log: FIXEOL first _socket functions are translated and pass the tests Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Sun Oct 16 10:48:23 2005 @@ -1,4 +1,3 @@ - import socket, errno, sys from pypy.interpreter.typedef import TypeDef from pypy.interpreter.baseobjspace import Wrappable @@ -71,13 +70,16 @@ else: import os def socket_strerror(errno): - return os.strerror(errno) + try: + return os.strerror(errno) + except TypeError: + return errno def wrap_socketerror(space, e): assert isinstance(e, socket.error) errno = e.args[0] msg = socket_strerror(errno) - + w_module = space.getbuiltinmodule('_socket') if isinstance(e, socket.gaierror): w_errortype = space.getattr(w_module, space.wrap('gaierror')) @@ -85,16 +87,16 @@ w_errortype = space.getattr(w_module, space.wrap('herror')) else: w_errortype = space.getattr(w_module, space.wrap('error')) - + return OperationError(w_errortype, space.wrap(errno), space.wrap(msg)) def wrap_timeouterror(space): - + w_module = space.getbuiltinmodule('_socket') w_error = space.getattr(w_module, space.wrap('timeout')) - + w_error = space.call_function(w_error, space.wrap("timed out")) return w_error @@ -248,10 +250,10 @@ raise OperationError(space.w_TypeError, space.wrap("expected int/long, %s found" % (space.type(w_x).getname(space, "?")))) - + return space.wrap(socket.ntohl(x)) ntohl.unwrap_spec = [ObjSpace, W_Root] - + def htons(space, x): """htons(integer) -> integer @@ -259,7 +261,7 @@ """ return space.wrap(socket.htons(x)) htons.unwrap_spec = [ObjSpace, int] - + def htonl(space, w_x): """htonl(integer) -> integer @@ -273,7 +275,7 @@ raise OperationError(space.w_TypeError, space.wrap("expected int/long, %s found" % (space.type(w_x).getname(space, "?")))) - + return space.wrap(socket.htonl(x)) htonl.unwrap_spec = [ObjSpace, W_Root] @@ -337,7 +339,7 @@ port = str(space.int_w(w_port)) else: port = space.str_w(w_port) - + try: return space.wrap(socket.getaddrinfo(host, port, family, socktype, proto, flags)) except socket.error, e: @@ -359,13 +361,13 @@ # # Timeout management -class State: +class State: def __init__(self, space): self.space = space - + self.defaulttimeout = -1 # Default timeout for new sockets - -def getstate(space): + +def getstate(space): return space.fromcache(State) def setdefaulttimeout(space, w_timeout): @@ -404,7 +406,7 @@ socket.setdefaulttimeout(None) else: socket.setdefaulttimeout(timeout) - + try: fd = socket.socket(family, type, proto) except socket.error, e: @@ -414,7 +416,7 @@ return space.wrap(sock) descr_socket_new = interp2app(newsocket, unwrap_spec=[ObjSpace, W_Root, int, int, int]) - + class Socket(Wrappable): "A wrappable box around an interp-level socket object." @@ -439,7 +441,7 @@ newsock = Socket(newfd, self.family, self.type, self.proto) return space.wrap((newsock, address)) accept.unwrap_spec = ['self', ObjSpace] - + def bind(self, space, w_addr): """bind(address) @@ -453,7 +455,7 @@ except socket.error, e: raise wrap_socketerror(space, e) bind.unwrap_spec = ['self', ObjSpace, W_Root] - + def close(self, space): """close() @@ -479,7 +481,7 @@ except socket.error, e: raise wrap_socketerror(space, e) connect.unwrap_spec = ['self', ObjSpace, W_Root] - + def connect_ex(self, space, w_addr): """connect_ex(address) -> errno @@ -492,7 +494,7 @@ except socket.error, e: return space.wrap(e.errno) connect_ex.unwrap_spec = ['self', ObjSpace, W_Root] - + def dup(self, space): """dup() -> socket object @@ -537,7 +539,7 @@ except socket.error, e: raise wrap_socketerror(space, e) getsockname.unwrap_spec = ['self', ObjSpace] - + def getsockopt(self, space, level, option, w_buffersize=NoneNotWrapped): """getsockopt(level, option[, buffersize]) -> value @@ -554,7 +556,7 @@ except socket.error, e: raise wrap_socketerror(space, e) getsockopt.unwrap_spec = ['self', ObjSpace, int, int, W_Root] - + def listen(self, space, backlog): """listen(backlog) @@ -567,7 +569,7 @@ except socket.error, e: raise wrap_socketerror(space, e) listen.unwrap_spec = ['self', ObjSpace, int] - + def makefile(self, space, mode="r", buffersize=-1): """makefile([mode[, buffersize]]) -> file object @@ -618,7 +620,7 @@ except socket.error, e: raise wrap_socketerror(space, e) send.unwrap_spec = ['self', ObjSpace, str, int] - + def sendall(self, space, data, flags=0): """sendall(data[, flags]) @@ -632,7 +634,7 @@ except socket.error, e: raise wrap_socketerror(space, e) sendall.unwrap_spec = ['self', ObjSpace, str, int] - + def sendto(self, space, data, w_param2, w_param3=NoneNotWrapped): """sendto(data[, flags], address) -> count @@ -652,7 +654,7 @@ except socket.error, e: raise wrap_socketerror(space, e) sendto.unwrap_spec = ['self', ObjSpace, str, W_Root, W_Root] - + def setblocking(self, space, flag): """setblocking(flag) @@ -672,7 +674,7 @@ Set a socket option. See the Unix manual for level and option. The value argument can either be an integer or a string. """ - + if space.is_true(space.isinstance(w_value, space.w_str)): strvalue = space.str_w(w_value) self.fd.setsockopt(level, option, strvalue) Modified: pypy/dist/pypy/module/_socket/rpython/exttable.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/exttable.py (original) +++ pypy/dist/pypy/module/_socket/rpython/exttable.py Sun Oct 16 10:48:23 2005 @@ -11,3 +11,6 @@ # Built-in functions needed in the rtyper declare(_socket.ntohs, int, '%s/ntohs' % module) +declare(_socket.htons, int, '%s/ntohs' % module) +declare(_socket.ntohl, int, '%s/ntohl' % module) +declare(_socket.htonl, int, '%s/htonl' % module) Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Sun Oct 16 10:48:23 2005 @@ -3,3 +3,15 @@ def ll__socket_ntohs(htons): return _socket.ntohs(htons) ll__socket_ntohs.suggested_primitive = True + +def ll__socket_htons(ntohs): + return _socket.ntohs(htons) +ll__socket_htons.suggested_primitive = True + +def ll__socket_htonl(ntohl): + return _socket.htonl(ntohl) +ll__socket_htonl.suggested_primitive = True + +def ll__socket_ntohl(htonl): + return _socket.ntohl(htonl) +ll__socket_ntohl.suggested_primitive = True Modified: pypy/dist/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/dist/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/dist/pypy/module/_socket/test/test_socket2.py Sun Oct 16 10:48:23 2005 @@ -152,9 +152,9 @@ w_l = space.appexec([w_socket, space.wrap(unicode(host)), space.wrap(port)], "(_socket, host, port): return _socket.getaddrinfo(host, port)") assert space.unwrap(w_l) == info - + def test_getnameinfo(): - host = "localhost" + host = "127.0.0.1" port = 25 info = socket.getnameinfo((host, port), 0) w_l = space.appexec([w_socket, space.wrap(host), space.wrap(port)], Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Sun Oct 16 10:48:23 2005 @@ -55,6 +55,9 @@ ll_stack.ll_stack_unwind: 'LL_stack_unwind', ll_stack.ll_stack_too_big: 'LL_stack_too_big', ll__socket.ll__socket_ntohs: 'LL__socket_ntohs', + ll__socket.ll__socket_htons: 'LL__socket_htons', + ll__socket.ll__socket_htonl: 'LL__socket_htonl', + ll__socket.ll__socket_ntohl: 'LL__socket_htonl', } #______________________________________________________ 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 Sun Oct 16 10:48:23 2005 @@ -39,6 +39,7 @@ # include "src/ll_strtod.h" # include "src/ll_thread.h" # include "src/ll_stackless.h" +# include "src/ll__socket.h" #endif #include "src/stack.h" Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Sun Oct 16 10:48:23 2005 @@ -7,7 +7,9 @@ #endif int LL__socket_ntohs(int htons); - +int LL__socket_htons(int ntohs); +long LL__socket_ntohl(long htonl); +long LL__socket_htonl(long ntohl); #ifndef PYPY_NOT_MAIN_FILE @@ -18,4 +20,25 @@ } +int LL__socket_htons(int ntohs) +{ + + return (int)htons((short) ntohs); + +} + +long LL__socket_ntohl(long htonl) +{ + + return ntohl(htonl); + +} + +long LL__socket_htonl(long ntohl) +{ + + return htonl(ntohl); + +} + #endif 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 Oct 16 10:48:23 2005 @@ -169,7 +169,7 @@ 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) + assert f(4.0, 0.5) == math.pow(4.0, 0.5) def test_math_frexp(): from math import frexp @@ -201,7 +201,7 @@ import random import math mathfn = getattr(math, funcname) - print funcname, + print funcname, def fn(x): return mathfn(x) f = compile(fn, [float]) @@ -235,7 +235,7 @@ #print mathf, v, r u = f(v) assert u == r - + check(math.log, f, -1.0) check(math.log, f, 0.0) @@ -284,7 +284,7 @@ return parts_to_float(sign, beforept, afterpt, exponent) f = compile(fn, [str, str, str, str]) - + data = [ (("","1","","") , 1.0), (("-","1","","") , -1.0), @@ -498,11 +498,50 @@ f() assert _real_getenv('ABCDEF') is None -def INPROGRESStest_socket(): +def test_socket(): import _socket import pypy.module._socket.rpython.exttable # for declare()/declaretype() def fn(): - print _socket.ntohs(123) + return _socket.ntohs(123) + f = compile(fn, []) + assert f() == _socket.ntohs(123) + def fn(): + return _socket.htons(123) + f = compile(fn, []) + assert f() == _socket.htons(123) + def fn(): + return _socket.ntohl(123) f = compile(fn, []) - f() + assert f() == _socket.ntohl(123) + def fn(): + return _socket.htonl(123) + f = compile(fn, []) + assert f() == _socket.htonl(123) + +def INPROGRESStest_NtoH(): + import _socket + # This just checks that htons etc. are their own inverse, + # when looking at the lower 16 or 32 bits. + def fn1(n): + return _socket.htonl(n) + def fn2(n): + return _socket.ntohl(n) + def fn3(n): + return _socket.ntohs(n) + def fn4(n): + return _socket.htons(n) + sizes = {compile(fn1, [int]): 32, compile(fn2, [int]): 32, + compile(fn4, [int]): 16, compile(fn3, [int]): 16} + for func, size in sizes.items(): + mask = (1L< Author: arigo Date: Sun Oct 16 10:56:03 2005 New Revision: 18669 Modified: pypy/dist/pypy/interpreter/argument.py pypy/dist/pypy/translator/c/src/mem.h Log: * avoid a slice where stop < start (crashes after translation). * make sure we catch mallocs of negative size. Modified: pypy/dist/pypy/interpreter/argument.py ============================================================================== --- pypy/dist/pypy/interpreter/argument.py (original) +++ pypy/dist/pypy/interpreter/argument.py Sun Oct 16 10:56:03 2005 @@ -177,7 +177,7 @@ # note that for this purpose we ignore the first blind_arguments, # which were put into place by prepend(). This way, keywords do # not conflict with the hidden extra argument bound by methods. - if kwds_w: + if kwds_w and input_argcount > self.blind_arguments: for name in argnames[self.blind_arguments:input_argcount]: if name in kwds_w: raise ArgErrMultipleValues(name) 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 Sun Oct 16 10:56:03 2005 @@ -9,7 +9,7 @@ #define MAXIMUM_MALLOCABLE_SIZE (LONG_MAX-4096) #define OP_MAX_VARSIZE(numitems, itemtype, err) { \ - if ((numitems) > (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype))) \ + if (((unsigned)(numitems)) > (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype)))\ FAIL_EXCEPTION(err, PyExc_MemoryError, "addr space overflow"); \ } From arigo at codespeak.net Sun Oct 16 11:09:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 16 Oct 2005 11:09:43 +0200 (CEST) Subject: [pypy-svn] r18670 - in pypy/dist/pypy/interpreter: . test Message-ID: <20051016090943.9B31B27B43@code1.codespeak.net> Author: arigo Date: Sun Oct 16 11:09:42 2005 New Revision: 18670 Modified: pypy/dist/pypy/interpreter/function.py pypy/dist/pypy/interpreter/test/test_function.py Log: More method object repr tweaking. Now we have the same as CPython's user-defined methods. (No chance to get coherent here, as CPython differs in the repr of user-defined or built-in methods). Fix the test. Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Sun Oct 16 11:09:42 2005 @@ -270,7 +270,8 @@ s = "" % (typename, name) return space.wrap(s) else: - info = 'bound method %s.%s' % (typename, name) + objrepr = space.str_w(space.repr(self.w_instance)) + info = 'bound method %s.%s of %s' % (typename, name, objrepr) # info = "method %s of %s object" % (name, typename) return self.w_instance.getrepr(self.space, info) Modified: pypy/dist/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_function.py (original) +++ pypy/dist/pypy/interpreter/test/test_function.py Sun Oct 16 11:09:42 2005 @@ -194,20 +194,17 @@ assert (c.m != c.m) is False def test_method_repr(self): - assert repr(dict.items) == "" class A(object): def f(self): pass - assert repr(A.f) == "" - assert repr(A().f).startswith("" + assert repr(A().f).startswith("" - assert repr(B().f).startswith("" + assert repr(B().f).startswith(" Author: tismer Date: Sun Oct 16 11:34:00 2005 New Revision: 18671 Added: pypy/dist/pypy/translator/locality/ pypy/dist/pypy/translator/locality/__init__.py pypy/dist/pypy/translator/locality/simulation.py pypy/dist/pypy/translator/locality/test/ pypy/dist/pypy/translator/locality/test/test_simulation.py Log: a little call simulator for function transition statistics. More to come, soon... Added: pypy/dist/pypy/translator/locality/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/locality/__init__.py Sun Oct 16 11:34:00 2005 @@ -0,0 +1 @@ +# \ No newline at end of file Added: pypy/dist/pypy/translator/locality/simulation.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/locality/simulation.py Sun Oct 16 11:34:00 2005 @@ -0,0 +1,162 @@ +""" + +Simulation of function calls +---------------------------- + +The purpose of this module is to simulate function calls +in the call-graph of a program, to gather information +about frequencies of transitions between functions. + +The following DemoNode/DemoSim classes show an example of the +simulation performed. They can be subclassed to connect them +to client structures like flowgraphs. + +- DemoSim.run was used to get an obviously correct reference implementation. + +- DemoSim.sim_all simulates the calls of the run method. The results are + exactly the same, although the computation time ir orders of magnitudes + smaller, and the DemoSim.simulate method is able to handle recursions + and function call probabilities which are fractions. +""" + + +class DemoNode: + def __init__(self, sim, func): + self.sim = sim + self.func = func + self.name = self._get_name(func) + self.callees = [] + self.calls = 0 + + def _get_name(self, func): + # to be overridden + return func.__name__ + + def _find_callee_names(self): + # to be overridden + return self.func.func_code.co_names + + def call(self): + self.calls += 1 + for i in range(self.sim.repetitions_per_call): + for func in self.callees: + self.sim.record_transition(self, func) + func.call() + + def clear(self): + self.calls = 0 + + def simulate_call(self, weight=1): + self.calls += weight + + +class DemoSim: + def __init__(self, funcnodes, nodefactory=DemoNode): + self.nodes = [] + self.transitions = {} + self.pending = {} + + name2node = {} + for func in funcnodes: + node = nodefactory(self, func) + name2node[node.name] = node + self.nodes.append(node) + self._names_width = self._find_names_width() + for node in self.nodes: + for name in node._find_callee_names(): + callee = name2node[name] + node.callees.append(callee) + self.transitions[ (node, callee) ] = 0 + + def _find_names_width(self): + n = 0 + for node in self.nodes: + n = max(n, len(node.name)) + return n + + def record_transition(self, caller, callee, weight=1): + self.transitions[ (caller, callee) ] += weight + + def run(self, reps=1, root=0): + self.repetitions_per_call = reps + root = self.nodes[root] + root.call() + + def run_all(self, reps=1): + for root in range(len(self.nodes)): + self.run(reps, root) + + def clear(self): + for key in self.transitions: + self.transitions[key] = 0 + for node in self.nodes: + node.clear() + + def display(self): + d = {'w': max(self._names_width, 6) } + print '%%%(w)ds %%%(w)ds repetition' % d % ('caller', 'callee') + for caller, callee, reps in self.get_state(): + print '%%%(w)ds %%%(w)ds %%6d' % d % (caller, callee, reps) + print '%%%(w)ds calls' % d % 'node' + for node in self.nodes: + print '%%%(w)ds %%6d' % d % (node.name, node.calls) + + def get_state(self): + lst = [] + for (caller, callee), reps in self.transitions.items(): + lst.append( (caller.name, callee.name, reps) ) + lst.sort() + return lst + + def simulate(self, call_prob=1, root=None): + # simulating runs by not actually calling, but shooting + # the transitions in a weighted manner. + # this allows us to handle recursions as well. + # first, stimulate nodes if no transitions are pending + if not self.pending: + if root is not None: + startnodes = [self.nodes[root]] + else: + startnodes = self.nodes + for node in startnodes: + self.pending[node] = 1 + # perform a single step of simulated calls. + pending = {} + for caller, ntrans in self.pending.items(): + caller.simulate_call(ntrans) + for callee in caller.callees: + self.record_transition(caller, callee, ntrans * call_prob) + pending[callee] = pending.get(callee, 0) + ntrans * call_prob + self.pending = pending + + def sim_all(self, call_prob=1, root=None): + # for testing, only. Would run infinitely with recursions. + self.simulate(call_prob, root) + while self.pending: + self.simulate(call_prob) + +# sample functions for proof of correctness + +def test(debug=False): + + def a(): b(); c(); d() + def b(): c(); d() + def c(): pass + def d(): c(); e() + def e(): c() + sim = DemoSim([a, b, c, d, e]) + if debug: + globals().update(locals()) + + sim.clear() + for prob in 1, 2, 3: + sim.clear() + sim.run_all(prob) + state1 = sim.get_state() + sim.clear() + sim.sim_all(prob) + state2 = sim.get_state() + assert state1 == state2 + +if __name__ == '__main__': + test() Added: pypy/dist/pypy/translator/locality/test/test_simulation.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/locality/test/test_simulation.py Sun Oct 16 11:34:00 2005 @@ -0,0 +1,4 @@ +from pypy.translator.locality import simulation + +def test_sim(): + simulation.test() From tismer at codespeak.net Sun Oct 16 11:35:22 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 16 Oct 2005 11:35:22 +0200 (CEST) Subject: [pypy-svn] r18672 - in pypy/dist/pypy/translator/locality: . test Message-ID: <20051016093522.5D77827B3B@code1.codespeak.net> Author: tismer Date: Sun Oct 16 11:35:20 2005 New Revision: 18672 Modified: pypy/dist/pypy/translator/locality/__init__.py (props changed) pypy/dist/pypy/translator/locality/simulation.py (contents, props changed) pypy/dist/pypy/translator/locality/test/test_simulation.py (contents, props changed) Log: eol-style Modified: pypy/dist/pypy/translator/locality/simulation.py ============================================================================== --- pypy/dist/pypy/translator/locality/simulation.py (original) +++ pypy/dist/pypy/translator/locality/simulation.py Sun Oct 16 11:35:20 2005 @@ -1,162 +1,162 @@ -""" - -Simulation of function calls ----------------------------- - -The purpose of this module is to simulate function calls -in the call-graph of a program, to gather information -about frequencies of transitions between functions. - -The following DemoNode/DemoSim classes show an example of the -simulation performed. They can be subclassed to connect them -to client structures like flowgraphs. - -- DemoSim.run was used to get an obviously correct reference implementation. - -- DemoSim.sim_all simulates the calls of the run method. The results are - exactly the same, although the computation time ir orders of magnitudes - smaller, and the DemoSim.simulate method is able to handle recursions - and function call probabilities which are fractions. -""" - - -class DemoNode: - def __init__(self, sim, func): - self.sim = sim - self.func = func - self.name = self._get_name(func) - self.callees = [] - self.calls = 0 - - def _get_name(self, func): - # to be overridden - return func.__name__ - - def _find_callee_names(self): - # to be overridden - return self.func.func_code.co_names - - def call(self): - self.calls += 1 - for i in range(self.sim.repetitions_per_call): - for func in self.callees: - self.sim.record_transition(self, func) - func.call() - - def clear(self): - self.calls = 0 - - def simulate_call(self, weight=1): - self.calls += weight - - -class DemoSim: - def __init__(self, funcnodes, nodefactory=DemoNode): - self.nodes = [] - self.transitions = {} - self.pending = {} - - name2node = {} - for func in funcnodes: - node = nodefactory(self, func) - name2node[node.name] = node - self.nodes.append(node) - self._names_width = self._find_names_width() - for node in self.nodes: - for name in node._find_callee_names(): - callee = name2node[name] - node.callees.append(callee) - self.transitions[ (node, callee) ] = 0 - - def _find_names_width(self): - n = 0 - for node in self.nodes: - n = max(n, len(node.name)) - return n - - def record_transition(self, caller, callee, weight=1): - self.transitions[ (caller, callee) ] += weight - - def run(self, reps=1, root=0): - self.repetitions_per_call = reps - root = self.nodes[root] - root.call() - - def run_all(self, reps=1): - for root in range(len(self.nodes)): - self.run(reps, root) - - def clear(self): - for key in self.transitions: - self.transitions[key] = 0 - for node in self.nodes: - node.clear() - - def display(self): - d = {'w': max(self._names_width, 6) } - print '%%%(w)ds %%%(w)ds repetition' % d % ('caller', 'callee') - for caller, callee, reps in self.get_state(): - print '%%%(w)ds %%%(w)ds %%6d' % d % (caller, callee, reps) - print '%%%(w)ds calls' % d % 'node' - for node in self.nodes: - print '%%%(w)ds %%6d' % d % (node.name, node.calls) - - def get_state(self): - lst = [] - for (caller, callee), reps in self.transitions.items(): - lst.append( (caller.name, callee.name, reps) ) - lst.sort() - return lst - - def simulate(self, call_prob=1, root=None): - # simulating runs by not actually calling, but shooting - # the transitions in a weighted manner. - # this allows us to handle recursions as well. - # first, stimulate nodes if no transitions are pending - if not self.pending: - if root is not None: - startnodes = [self.nodes[root]] - else: - startnodes = self.nodes - for node in startnodes: - self.pending[node] = 1 - # perform a single step of simulated calls. - pending = {} - for caller, ntrans in self.pending.items(): - caller.simulate_call(ntrans) - for callee in caller.callees: - self.record_transition(caller, callee, ntrans * call_prob) - pending[callee] = pending.get(callee, 0) + ntrans * call_prob - self.pending = pending - - def sim_all(self, call_prob=1, root=None): - # for testing, only. Would run infinitely with recursions. - self.simulate(call_prob, root) - while self.pending: - self.simulate(call_prob) - -# sample functions for proof of correctness - -def test(debug=False): - - def a(): b(); c(); d() - def b(): c(); d() - def c(): pass - def d(): c(); e() - def e(): c() - sim = DemoSim([a, b, c, d, e]) - if debug: - globals().update(locals()) - - sim.clear() - for prob in 1, 2, 3: - sim.clear() - sim.run_all(prob) - state1 = sim.get_state() - sim.clear() - sim.sim_all(prob) - state2 = sim.get_state() - assert state1 == state2 - -if __name__ == '__main__': - test() +""" + +Simulation of function calls +---------------------------- + +The purpose of this module is to simulate function calls +in the call-graph of a program, to gather information +about frequencies of transitions between functions. + +The following DemoNode/DemoSim classes show an example of the +simulation performed. They can be subclassed to connect them +to client structures like flowgraphs. + +- DemoSim.run was used to get an obviously correct reference implementation. + +- DemoSim.sim_all simulates the calls of the run method. The results are + exactly the same, although the computation time ir orders of magnitudes + smaller, and the DemoSim.simulate method is able to handle recursions + and function call probabilities which are fractions. +""" + + +class DemoNode: + def __init__(self, sim, func): + self.sim = sim + self.func = func + self.name = self._get_name(func) + self.callees = [] + self.calls = 0 + + def _get_name(self, func): + # to be overridden + return func.__name__ + + def _find_callee_names(self): + # to be overridden + return self.func.func_code.co_names + + def call(self): + self.calls += 1 + for i in range(self.sim.repetitions_per_call): + for func in self.callees: + self.sim.record_transition(self, func) + func.call() + + def clear(self): + self.calls = 0 + + def simulate_call(self, weight=1): + self.calls += weight + + +class DemoSim: + def __init__(self, funcnodes, nodefactory=DemoNode): + self.nodes = [] + self.transitions = {} + self.pending = {} + + name2node = {} + for func in funcnodes: + node = nodefactory(self, func) + name2node[node.name] = node + self.nodes.append(node) + self._names_width = self._find_names_width() + for node in self.nodes: + for name in node._find_callee_names(): + callee = name2node[name] + node.callees.append(callee) + self.transitions[ (node, callee) ] = 0 + + def _find_names_width(self): + n = 0 + for node in self.nodes: + n = max(n, len(node.name)) + return n + + def record_transition(self, caller, callee, weight=1): + self.transitions[ (caller, callee) ] += weight + + def run(self, reps=1, root=0): + self.repetitions_per_call = reps + root = self.nodes[root] + root.call() + + def run_all(self, reps=1): + for root in range(len(self.nodes)): + self.run(reps, root) + + def clear(self): + for key in self.transitions: + self.transitions[key] = 0 + for node in self.nodes: + node.clear() + + def display(self): + d = {'w': max(self._names_width, 6) } + print '%%%(w)ds %%%(w)ds repetition' % d % ('caller', 'callee') + for caller, callee, reps in self.get_state(): + print '%%%(w)ds %%%(w)ds %%6d' % d % (caller, callee, reps) + print '%%%(w)ds calls' % d % 'node' + for node in self.nodes: + print '%%%(w)ds %%6d' % d % (node.name, node.calls) + + def get_state(self): + lst = [] + for (caller, callee), reps in self.transitions.items(): + lst.append( (caller.name, callee.name, reps) ) + lst.sort() + return lst + + def simulate(self, call_prob=1, root=None): + # simulating runs by not actually calling, but shooting + # the transitions in a weighted manner. + # this allows us to handle recursions as well. + # first, stimulate nodes if no transitions are pending + if not self.pending: + if root is not None: + startnodes = [self.nodes[root]] + else: + startnodes = self.nodes + for node in startnodes: + self.pending[node] = 1 + # perform a single step of simulated calls. + pending = {} + for caller, ntrans in self.pending.items(): + caller.simulate_call(ntrans) + for callee in caller.callees: + self.record_transition(caller, callee, ntrans * call_prob) + pending[callee] = pending.get(callee, 0) + ntrans * call_prob + self.pending = pending + + def sim_all(self, call_prob=1, root=None): + # for testing, only. Would run infinitely with recursions. + self.simulate(call_prob, root) + while self.pending: + self.simulate(call_prob) + +# sample functions for proof of correctness + +def test(debug=False): + + def a(): b(); c(); d() + def b(): c(); d() + def c(): pass + def d(): c(); e() + def e(): c() + sim = DemoSim([a, b, c, d, e]) + if debug: + globals().update(locals()) + + sim.clear() + for prob in 1, 2, 3: + sim.clear() + sim.run_all(prob) + state1 = sim.get_state() + sim.clear() + sim.sim_all(prob) + state2 = sim.get_state() + assert state1 == state2 + +if __name__ == '__main__': + test() Modified: pypy/dist/pypy/translator/locality/test/test_simulation.py ============================================================================== --- pypy/dist/pypy/translator/locality/test/test_simulation.py (original) +++ pypy/dist/pypy/translator/locality/test/test_simulation.py Sun Oct 16 11:35:20 2005 @@ -1,4 +1,4 @@ -from pypy.translator.locality import simulation - -def test_sim(): - simulation.test() +from pypy.translator.locality import simulation + +def test_sim(): + simulation.test() From cfbolz at codespeak.net Sun Oct 16 11:38:17 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 16 Oct 2005 11:38:17 +0200 (CEST) Subject: [pypy-svn] r18673 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051016093817.6DB4B27B40@code1.codespeak.net> Author: cfbolz Date: Sun Oct 16 11:38:15 2005 New Revision: 18673 Modified: pypy/dist/pypy/rpython/l3interp/model.py pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: (pedronis, cfbolz): remove int_inputargs, because it is not needed Modified: pypy/dist/pypy/rpython/l3interp/model.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/model.py (original) +++ pypy/dist/pypy/rpython/l3interp/model.py Sun Oct 16 11:38:15 2005 @@ -112,12 +112,11 @@ pass class Block(object): - def __init__(self, int_a, exitswitch, exits): + def __init__(self, exitswitch, exits): self.operations = [] # list of Operations self.exitswitch = exitswitch # positives are variables # negatives see above self.exits = exits # list of Links - self.int_inputargs = int_a # list of ints class Graph(object): def __init__(self, name, startlink): Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sun Oct 16 11:38:15 2005 @@ -18,7 +18,7 @@ # return 3 + 4 op = model.Operation(l3interp.LLFrame.op_int_add, 0, [-1, -2]) returnlink = model.ReturnLink() - block = model.Block([], model.ONE_EXIT, [returnlink]) + block = model.Block(model.ONE_EXIT, [returnlink]) block.operations.append(op) startlink = model.Link(block, []) graph = model.Graph("testgraph", startlink) @@ -42,7 +42,7 @@ # return x + 4 op = model.Operation(l3interp.LLFrame.op_int_add, 1, [0, -1]) returnlink = model.ReturnLink(return_val=1) - block = model.Block([], model.ONE_EXIT, [returnlink]) + block = model.Block(model.ONE_EXIT, [returnlink]) block.operations.append(op) startlink = model.Link(target=block) startlink.move_int_registers = [0, 0] @@ -70,7 +70,7 @@ op = model.Operation(l3interp.LLFrame.op_int_is_true, 1, [0]) returnlink1 = model.ReturnLink(-1) returnlink2 = model.ReturnLink(-2) - block = model.Block([], 1, [returnlink1, returnlink2]) + block = model.Block(1, [returnlink1, returnlink2]) block.operations.append(op) startlink = model.Link(target=block) startlink.move_int_registers = [0, 0] @@ -91,3 +91,4 @@ fn = translate(eval_branch, [int]) assert fn(4) == 2 assert fn(0) == 1 + From mwh at codespeak.net Sun Oct 16 11:53:02 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 16 Oct 2005 11:53:02 +0200 (CEST) Subject: [pypy-svn] r18674 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem ootypesystem/test Message-ID: <20051016095302.66E5127B43@code1.codespeak.net> Author: mwh Date: Sun Oct 16 11:52:59 2005 New Revision: 18674 Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/rpbc.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/rpbc.py Log: (boria, mwh, bert, samuele, arigo, anyone else who wants some credit/blame :) * move a large part of lltypesystem.rpbc.MethodsPBCRepr back into rpbc as AbstractMethodsPBCRepr and have what's left inherit from this. * implement ootypesystem.rpbc.MethodsPBCRepr. * extend ootypesystem.rclass.InstanceRepr to have some support for methods (no support for overriding yet). * enable a simple test that calls a method. Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Sun Oct 16 11:52:59 2005 @@ -12,7 +12,7 @@ from pypy.rpython.rpbc import SingleFrozenPBCRepr, getsignature, samesig,\ commonbase, allattributenames, get_access_set,\ MultiplePBCRepr, FunctionsPBCRepr, \ - AbstractClassesPBCRepr + AbstractClassesPBCRepr, AbstractMethodsPBCRepr from pypy.rpython.lltypesystem import rclass from pypy.tool.sourcetools import has_varargs @@ -174,59 +174,11 @@ # ____________________________________________________________ -class MethodsPBCRepr(Repr): +class MethodsPBCRepr(AbstractMethodsPBCRepr): """Representation selected for a PBC of the form {func: classdef...}. It assumes that all the methods come from the same name in a base classdef.""" - def __init__(self, rtyper, s_pbc): - self.rtyper = rtyper - self.s_pbc = s_pbc - if None in s_pbc.prebuiltinstances: - raise TyperError("unsupported: variable of type " - "bound-method-object or None") - basedef = commonbase(s_pbc.prebuiltinstances.values()) - for classdef1, name in allattributenames(basedef): - # don't trust the func.func_names and see if this 'name' would be - # the one under which we can find all these methods - for func, classdef in s_pbc.prebuiltinstances.items(): - try: - if func != getattr(classdef.cls, name).im_func: - break - except AttributeError: - break - else: - # yes! - self.methodname = name - self.classdef = classdef1 # where the Attribute is defined - break - else: - raise TyperError("cannot find a unique name under which the " - "methods can be found: %r" % ( - s_pbc.prebuiltinstances,)) - # the low-level representation is just the bound 'self' argument. - self.s_im_self = annmodel.SomeInstance(self.classdef) - self.r_im_self = rclass.getinstancerepr(rtyper, self.classdef) - self.lowleveltype = self.r_im_self.lowleveltype - - def convert_const(self, method): - if getattr(method, 'im_func', None) is None: - raise TyperError("not a bound method: %r" % method) - return self.r_im_self.convert_const(method.im_self) - - def get_r_implfunc(self): - r_class = self.r_im_self.rclass - mangled_name, r_func = r_class.clsfields[self.methodname] - return r_func, 1 - - def get_s_callable(self): - return self.s_pbc - - def get_method_from_instance(self, r_inst, v_inst, llops): - # The 'self' might have to be cast to a parent class - # (as shown for example in test_rclass/test_method_both_A_and_B) - return llops.convertvar(v_inst, r_inst, self.r_im_self) - def rtype_hardwired_simple_call(self, hop): return self.redispatch_call(hop, call_args=False, hardwired=True) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sun Oct 16 11:52:59 2005 @@ -1,6 +1,7 @@ from pypy.rpython.rmodel import inputconst from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \ getinstancerepr +from pypy.rpython.rpbc import getsignature from pypy.rpython.ootypesystem import ootype CLASSTYPE = ootype.Class @@ -28,6 +29,7 @@ self.lowleveltype = ootype.Instance(classdef.cls.__name__, b, {}, {}) self.prebuiltinstances = {} # { id(x): (x, _ptr) } + self.allmethods = {} def _setup_repr(self): # FIXME methods @@ -41,6 +43,23 @@ fields[name] = oot ootype.addFields(self.lowleveltype, fields) + + methods = {} + baseInstance = self.lowleveltype._superclass + + for name, attrdef in attrs: + if attrdef.readonly: + assert len(attrdef.s_value.prebuiltinstances) == 1, 'no support for overridden methods yet' + # XXX following might not always succeed + impl = self.classdef.cls.__dict__[name] + + f, inputs, ret = getsignature(self.rtyper, impl) + M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) + m = ootype.meth(M, _name=name, _callable=impl) + + methods[name] = m + + ootype.addMethods(self.lowleveltype, methods) def rtype_getattr(self, hop): attr = hop.args_s[1].const Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Sun Oct 16 11:52:59 2005 @@ -1,6 +1,8 @@ -from pypy.rpython.rpbc import AbstractClassesPBCRepr +from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr from pypy.rpython.rclass import rtype_new_instance from pypy.rpython.ootypesystem import ootype +from pypy.rpython.ootypesystem.rclass import InstanceRepr +from pypy.annotation.pairtype import pairtype class ClassesPBCRepr(AbstractClassesPBCRepr): def rtype_simple_call(self, hop): @@ -10,3 +12,19 @@ klass = self.s_pbc.const v_instance = rtype_new_instance(hop.rtyper, klass, hop.llops) return v_instance + + +class MethodsPBCRepr(AbstractMethodsPBCRepr): + + def rtype_simple_call(self, hop): + vlist = hop.inputargs(self, *hop.args_r[1:]) + cname = hop.inputconst(ootype.Void, self.methodname) + return hop.genop("oosend", [cname]+vlist, + resulttype = hop.r_result.lowleveltype) + + + +class __extend__(pairtype(InstanceRepr, MethodsPBCRepr)): + + def convert_from_to(_, v, llops): + return v Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sun Oct 16 11:52:59 2005 @@ -81,8 +81,8 @@ return 1 def test_method(): - py.test.skip('in progress') def dummyfn(): inst = HasAMethod() return inst.f() - specialize(dummyfn, [])#, viewBefore=True) + result = interpret(dummyfn, [], type_system='ootype') + assert result == 1 Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Sun Oct 16 11:52:59 2005 @@ -361,6 +361,59 @@ return inputconst(r_clspbc2, r_clspbc1.s_pbc.const) return NotImplemented +class AbstractMethodsPBCRepr(Repr): + """Representation selected for a PBC of the form {func: classdef...}. + It assumes that all the methods come from the same name in a base + classdef.""" + + def __init__(self, rtyper, s_pbc): + self.rtyper = rtyper + self.s_pbc = s_pbc + if None in s_pbc.prebuiltinstances: + raise TyperError("unsupported: variable of type " + "bound-method-object or None") + basedef = commonbase(s_pbc.prebuiltinstances.values()) + for classdef1, name in allattributenames(basedef): + # don't trust the func.func_names and see if this 'name' would be + # the one under which we can find all these methods + for func, classdef in s_pbc.prebuiltinstances.items(): + try: + if func != getattr(classdef.cls, name).im_func: + break + except AttributeError: + break + else: + # yes! + self.methodname = name + self.classdef = classdef1 # where the Attribute is defined + break + else: + raise TyperError("cannot find a unique name under which the " + "methods can be found: %r" % ( + s_pbc.prebuiltinstances,)) + # the low-level representation is just the bound 'self' argument. + self.s_im_self = annmodel.SomeInstance(self.classdef) + self.r_im_self = rclass.getinstancerepr(rtyper, self.classdef) + self.lowleveltype = self.r_im_self.lowleveltype + + def convert_const(self, method): + if getattr(method, 'im_func', None) is None: + raise TyperError("not a bound method: %r" % method) + return self.r_im_self.convert_const(method.im_self) + + def get_r_implfunc(self): + r_class = self.r_im_self.rclass + mangled_name, r_func = r_class.clsfields[self.methodname] + return r_func, 1 + + def get_s_callable(self): + return self.s_pbc + + def get_method_from_instance(self, r_inst, v_inst, llops): + # The 'self' might have to be cast to a parent class + # (as shown for example in test_rclass/test_method_both_A_and_B) + return llops.convertvar(v_inst, r_inst, self.r_im_self) + # ____________________________________________________________ def getsignature(rtyper, func): From mwh at codespeak.net Sun Oct 16 12:02:28 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 16 Oct 2005 12:02:28 +0200 (CEST) Subject: [pypy-svn] r18675 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20051016100228.1680D27B43@code1.codespeak.net> Author: mwh Date: Sun Oct 16 12:02:26 2005 New Revision: 18675 Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py Log: explicitify one of our limitations. Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sun Oct 16 12:02:26 2005 @@ -49,6 +49,8 @@ for name, attrdef in attrs: if attrdef.readonly: + # if the following line suffers an AttributeError, + # maybe the attr is actually not a method. assert len(attrdef.s_value.prebuiltinstances) == 1, 'no support for overridden methods yet' # XXX following might not always succeed impl = self.classdef.cls.__dict__[name] From ericvrp at codespeak.net Sun Oct 16 12:26:47 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Sun, 16 Oct 2005 12:26:47 +0200 (CEST) Subject: [pypy-svn] r18676 - in pypy/dist/pypy/translator/js: . test Message-ID: <20051016102647.9D3C527B43@code1.codespeak.net> Author: ericvrp Date: Sun Oct 16 12:26:46 2005 New Revision: 18676 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/gc.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/opaquenode.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py pypy/dist/pypy/translator/js/test/runtest.py Log: * Major cleanup. Removed all repr_type, TypeNodes and friends since they were not used. * Fixed mallocs [97 passing] (with inlining and malloc removal it's 102) Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Sun Oct 16 12:26:46 2005 @@ -4,64 +4,7 @@ from pypy.translator.js.log import log 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 - 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 - # constructor_decl is used to declare the constructor - # for the array type (see writeimpl) - 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 = 'new Array' - self.constructor_decl = "%s(len)" % self.constructor_ref - - def __str__(self): - return "" % self.ref - - def setup(self): - self.db.prepare_type(self.arraytype) - - # ______________________________________________________________________ - # entry points from genllvm - # - #def writedatatypedecl(self, codewriter): - # codewriter.arraydef(self.ref, - # 'int', - # self.db.repr_type(self.arraytype)) - - #def writedecl(self, codewriter): - # # declaration for constructor - # codewriter.declare(self.constructor_decl) - - -class VoidArrayTypeNode(LLVMNode): - __slots__ = "db array ref".split() - - 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 { int }" % self.ref - # codewriter.append(td) - class ArrayNode(ConstantLLVMNode): """ An arraynode. Elements can be a primitive, @@ -76,7 +19,7 @@ self.value = value self.arraytype = lltype.typeOf(value).OF prefix = 'arrayinstance' - name = '' #str(value).split()[1] + name = '' #XXX how to get the name self.ref = self.make_ref(prefix, name) def __str__(self): @@ -92,8 +35,8 @@ self.db.prepare_constant(lltype.typeOf(p), p) def writedecl(self, codewriter): - if self.arraytype is lltype.Char: #or use seperate nodetype - codewriter.declare(self.ref + ' = new String()') + if self.arraytype is lltype.Char: + codewriter.declare(self.ref + ' = new String()') #XXX string should be earlier else: codewriter.declare(self.ref + ' = new Array()') @@ -108,28 +51,18 @@ r = "[%s]" % ", ".join([self.db.repr_constant(v)[1] for v in items]) return l, r - #def get_typerepr(self): - # arraylen = self.get_arrayvalue()[0] - # typeval = self.db.repr_type(self.arraytype) - # return "{ int, [%s x %s] }" % (arraylen, typeval) - def get_ref(self): return self.ref - #typeval = self.db.repr_type(lltype.typeOf(self.value)) - #ref = "cast (%s* %s to %s*)" % (self.get_typerepr(), self.ref, typeval) - #p, c = lltype.parentlink(self.value) - #assert p is None, "child arrays are NOT needed by rtyper" - #return ref - def get_pbcref(self, toptr): - return self.ref - #ref = self.ref - #p, c = lltype.parentlink(self.value) - #assert p is None, "child arrays are NOT needed by rtyper" - # - #fromptr = "%s*" % self.get_typerepr() - #ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) - #return ref + #def get_pbcref(self, toptr): + # return self.ref + # #ref = self.ref + # #p, c = lltype.parentlink(self.value) + # #assert p is None, "child arrays are NOT needed by rtyper" + # # + # #fromptr = "%s*" % self.get_typerepr() + # #ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) + # #return ref def get_childref(self, index): return "getelementptr(%s* %s, int 0, uint 1, int %s)" %( @@ -141,16 +74,7 @@ physicallen, arrayrepr = self.get_arrayvalue() return arrayrepr - ## first length is logical, second is physical - #typeval = self.db.repr_type(self.arraytype) - #value = "int %s, [%s x %s] %s" % (self.get_length(), - # physicallen, - # typeval, - # arrayrepr) - # - #s = "%s {%s}" % (self.get_typerepr(), value) - #return s - + class StrArrayNode(ArrayNode): __slots__ = "".split() @@ -172,6 +96,7 @@ r = '"%s"' % "".join(s) return item_length, r + class VoidArrayNode(ConstantLLVMNode): __slots__ = "db value ref".split() @@ -179,8 +104,8 @@ assert isinstance(lltype.typeOf(value), lltype.Array) self.db = db self.value = value - prefix = 'arrayinstance' - name = '' #str(value).split()[1] + prefix = 'arrayinstance_Void' + name = '' self.ref = self.make_ref(prefix, name) def constantvalue(self): Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Sun Oct 16 12:26:46 2005 @@ -145,14 +145,11 @@ self.append("}", 1) self.append("};", 0) - def ret(self, type_, ref): - if type_ == 'void': - self.append("return") - else: - self.append("return " + ref) + def ret(self, ref=''): + self.append("return " + ref) self.skip_closeblock() - def binaryop(self, name, targetvar, type_, ref1, ref2): + def binaryop(self, name, targetvar, ref1, ref2): self.append("%(targetvar)s = %(ref1)s %(name)s %(ref2)s" % locals()) def neg(self, targetvar, source): @@ -172,10 +169,8 @@ self.append('%s = %s(%s)' % (targetvar, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): - #self.comment('codewriter cast 1 targettype=%(targettype)s, targetvar=%(targetvar)s, fromtype=%(fromtype)s, fromvar=%(fromvar)s' % locals()) if fromtype == 'void' and targettype == 'void': return - #self.comment('codewriter cast 2') if targettype == fromtype: self.append("%(targetvar)s = %(fromvar)s" % locals()) elif targettype in ('int','uint',): @@ -189,7 +184,7 @@ def malloc(self, targetvar, type_, size=1, atomic=False): for s in self.js.gcpolicy.malloc(targetvar, type_, size, atomic, 'word', 'uword').split('\n'): - self.llvm(s) + self.append(s) def getelementptr(self, targetvar, type, typevar, *indices): res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, word 0, " % locals() @@ -200,17 +195,11 @@ #res += ''.join(['[%s]' % i for t, i in indices]) #self.append(res) - #def load(self, targetvar, targettype, ptr): - # self.llvm("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals()) - def load(self, destvar, src, srcindices): res = "%(destvar)s = %(src)s" % locals() res += ''.join(['[%s]' % index for index in srcindices]) self.append(res) - #def store(self, valuetype, valuevar, ptr): - # self.llvm("store %(valuetype)s %(valuevar)s, %(valuetype)s* %(ptr)s" % locals()) - def store(self, dest, destindices, srcvar): res = dest res += ''.join(['[%s]' % index for index in destindices]) Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Sun Oct 16 12:26:46 2005 @@ -1,13 +1,11 @@ import sys -from pypy.translator.js.funcnode import FuncNode, FuncTypeNode +from pypy.translator.js.funcnode import FuncNode from pypy.translator.js.extfuncnode import ExternalFuncNode -from pypy.translator.js.structnode import StructNode, StructVarsizeNode, \ - StructTypeNode, StructVarsizeTypeNode -from pypy.translator.js.arraynode import ArrayNode, StrArrayNode, \ - VoidArrayNode, ArrayTypeNode, VoidArrayTypeNode -from pypy.translator.js.opaquenode import OpaqueNode, OpaqueTypeNode +from pypy.translator.js.structnode import StructNode, StructVarsizeNode +from pypy.translator.js.arraynode import ArrayNode, StrArrayNode, VoidArrayNode +from pypy.translator.js.opaquenode import OpaqueNode from pypy.translator.js.node import ConstantLLVMNode from pypy.rpython import lltype from pypy.objspace.flow.model import Constant, Variable @@ -112,37 +110,39 @@ self.obj2node[key] = node self._pendingsetup.append(node) - def prepare_type(self, type_): - if type_ in self.obj2node: - return - if isinstance(type_, lltype.Primitive): - pass - elif isinstance(type_, lltype.Ptr): - self.prepare_type(type_.TO) - - elif isinstance(type_, lltype.Struct): - if type_._arrayfld: - self.addpending(type_, StructVarsizeTypeNode(self, type_)) - else: - self.addpending(type_, StructTypeNode(self, type_)) - elif isinstance(type_, lltype.FuncType): - self.addpending(type_, FuncTypeNode(self, type_)) - - elif isinstance(type_, lltype.Array): - if type_.OF is lltype.Void: - self.addpending(type_, VoidArrayTypeNode(self, type_)) - else: - self.addpending(type_, ArrayTypeNode(self, type_)) - - elif isinstance(type_, lltype.OpaqueType): - self.addpending(type_, OpaqueTypeNode(self, type_)) - - else: - assert False, "need to prepare typerepr %s %s" % (type_, type(type_)) - - def prepare_type_multi(self, types): - for type_ in types: - self.prepare_type(type_) + #def prepare_type(self, type_): + # return #forget about the types in Javascript + # + # #if type_ in self.obj2node: + # # return + # #if isinstance(type_, lltype.Primitive): + # # pass + # #elif isinstance(type_, lltype.Ptr): + # # self.prepare_type(type_.TO) + # # + # #elif isinstance(type_, lltype.Struct): + # # if type_._arrayfld: + # # self.addpending(type_, StructVarsizeTypeNode(self, type_)) + # # else: + # # self.addpending(type_, StructTypeNode(self, type_)) + # #elif isinstance(type_, lltype.FuncType): + # # self.addpending(type_, FuncTypeNode(self, type_)) + # # + # #elif isinstance(type_, lltype.Array): + # # if type_.OF is lltype.Void: + # # self.addpending(type_, VoidArrayTypeNode(self, type_)) + # # else: + # # self.addpending(type_, ArrayTypeNode(self, type_)) + # # + # #elif isinstance(type_, lltype.OpaqueType): + # # self.addpending(type_, OpaqueTypeNode(self, type_)) + # # + # #else: + # # assert False, "need to prepare typerepr %s %s" % (type_, type(type_)) + # + #def prepare_type_multi(self, types): + # for type_ in types: + # self.prepare_type(type_) def prepare_constant(self, type_, value): if isinstance(type_, lltype.Primitive): @@ -165,7 +165,7 @@ self.addpending(value, self.create_constant_node(type_, value)) # always add type (it is safe) - self.prepare_type(type_) + #self.prepare_type(type_) def prepare_arg_value(self, const_or_var): """if const_or_var is not already in a dictionary self.obj2node, @@ -194,11 +194,8 @@ 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): while self._pendingsetup: node = self._pendingsetup.pop() @@ -230,41 +227,29 @@ assert isinstance(arg, Variable) return str(arg) - def repr_arg_type(self, arg): - assert isinstance(arg, (Constant, Variable)) - ct = arg.concretetype - return self.repr_type(ct) - - def repr_type(self, type_): + def repr_concretetype(self, ct): #used by casts try: - return self.obj2node[type_].ref + return self.obj2node[ct].ref except KeyError: - if isinstance(type_, lltype.Primitive): - return self.primitives[type_] - elif isinstance(type_, lltype.Ptr): - return '' #self.repr_type(type_.TO) + 'XXX*' + if isinstance(ct, lltype.Primitive): + return self.primitives[ct] + elif isinstance(ct, lltype.Ptr): + return '' #self.repr_concretetype(type_.TO) else: - raise TypeError("cannot represent %r" %(type_,)) - - def repr_argwithtype(self, arg): - return self.repr_arg(arg), self.repr_arg_type(arg) - + raise TypeError("cannot represent %r" % ct) + def repr_arg_multi(self, args): return [self.repr_arg(arg) for arg in args] - def repr_arg_type_multi(self, args): - return [self.repr_arg_type(arg) for arg in args] - def repr_constant(self, value): " returns node and repr as tuple " type_ = lltype.typeOf(value) if isinstance(type_, lltype.Primitive): repr = self.primitive_to_str(type_, value) return None, repr - #return None, "%s %s" % (self.repr_type(type_), repr) elif isinstance(type_, lltype.Ptr): - toptr = self.repr_type(type_) + toptr = '' #self.repr_type(type_) value = value._obj # special case, null pointer @@ -334,14 +319,6 @@ # __________________________________________________________ # 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 get_childref(self, parent, child): node = self.obj2node[parent] return node.get_childref(child) Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Sun Oct 16 12:26:46 2005 @@ -11,30 +11,6 @@ from pypy.translator.js.log import log log = log.funcnode -class FuncTypeNode(LLVMNode): - #def __init__(self, db, type_): - # #XXX not sure if we need FuncTypeNode with Javascript - # pass - - __slots__ = "db type_ ref".split() - - def __init__(self, db, type_): - self.db = db - assert isinstance(type_, lltype.FuncType) - self.type_ = type_ - self.ref = self.make_ref('functiontype', '') - - def __str__(self): - return "" % self.ref - - def setup(self): - self.db.prepare_type(self.type_.RESULT) - self.db.prepare_type_multi(self.type_._trueargs()) - - #def writedatatypedecl(self, codewriter): - # 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): __slots__ = "db value ref graph blockindex".split() @@ -75,11 +51,6 @@ assert self.graph, "cannot traverse" traverse(visit, self.graph) - # ______________________________________________________________________ - # main entry points from genllvm - #def writedecl(self, codewriter): - # codewriter.declare(self.getdecl()) - def writeimpl(self, codewriter): graph = self.graph log.writeimpl(graph.name) @@ -138,41 +109,13 @@ if a.concretetype is not lltype.Void] inputargs = self.db.repr_arg_multi(startblock_inputargs) - inputargtypes = self.db.repr_arg_type_multi(startblock_inputargs) - returntype = self.db.repr_arg_type(self.graph.returnblock.inputargs[0]) - #result = "%s %s" % (returntype, self.ref) - #args = ["%s %s" % item for item in zip(inputargtypes, inputargs)] - #result += "(%s)" % ", ".join(args) return self.ref + "(%s)" % ", ".join(inputargs) def write_block(self, codewriter, block): - #self.write_block_phi_nodes(codewriter, block) self.write_block_operations(codewriter, block) self.write_block_branches(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) - # inputargtypes = self.db.repr_arg_type_multi(block.inputargs) - # for i, (arg, type_) in enumerate(zip(inputargs, inputargtypes)): - # names = self.db.repr_arg_multi([link.args[i] for link in entrylinks]) - # blocknames = [self.blockindex[link.prevblock] for link in entrylinks] - # for i, link in enumerate(entrylinks): #XXX refactor into a transformation - # if link.prevblock.exitswitch == Constant(last_exception) and \ - # link.prevblock.exits[0].target != block: - # blocknames[i] += '_exception_found_branchto_' + self.blockindex[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": - # 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) if block.exitswitch == Constant(last_exception): #codewriter.comment('FuncNode(ConstantLLVMNode) *last_exception* write_block_branches @%s@' % str(block.exits)) return @@ -214,10 +157,11 @@ def write_returnblock(self, codewriter, block): assert len(block.inputargs) == 1 - #self.write_block_phi_nodes(codewriter, block) - inputargtype = self.db.repr_arg_type(block.inputargs[0]) - inputarg = self.db.repr_arg(block.inputargs[0]) - codewriter.ret(inputargtype, inputarg) + # #self.write_block_phi_nodes(codewriter, block) + # inputargtype = self.db.repr_arg_type(block.inputargs[0]) + # inputarg = self.db.repr_arg(block.inputargs[0]) + # codewriter.ret(inputargtype, inputarg) + codewriter.ret( self.db.repr_arg(block.inputargs[0]) ) def write_exceptblock(self, codewriter, block): self.db.genllvm.exceptionpolicy.write_exceptblock(self, codewriter, block) Modified: pypy/dist/pypy/translator/js/gc.py ============================================================================== --- pypy/dist/pypy/translator/js/gc.py (original) +++ pypy/dist/pypy/translator/js/gc.py Sun Oct 16 12:26:46 2005 @@ -62,6 +62,7 @@ ''' def malloc(self, targetvar, type_, size, is_atomic, word, uword): + return '%(targetvar)s = new Object()' % locals() s = str(size) self.n_malloced += 1 cnt = '.%d' % self.n_malloced Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Sun Oct 16 12:26:46 2005 @@ -86,17 +86,14 @@ # l = "%%%s = type %s" % (c_name, self.db.repr_type(obj)) # codewriter.append(l) - codewriter.comment("Function Implementation", 0) for typ_decl in self.db.getnodes(): typ_decl.writeimpl(codewriter) - codewriter.comment("Forward Declarations", 0) - #for typ_decl in self.db.getnodes(): - # typ_decl.writedatatypedecl(codewriter) + codewriter.newline() for typ_decl in self.db.getnodes(): typ_decl.writedecl(codewriter) - codewriter.comment("Global Data", 0) + codewriter.newline() for typ_decl in self.db.getnodes(): typ_decl.writeglobalconstants(codewriter) Modified: pypy/dist/pypy/translator/js/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/js/opaquenode.py (original) +++ pypy/dist/pypy/translator/js/opaquenode.py Sun Oct 16 12:26:46 2005 @@ -1,24 +1,6 @@ from pypy.translator.js.node import LLVMNode, ConstantLLVMNode from pypy.rpython import lltype -class OpaqueTypeNode(LLVMNode): - - def __init__(self, db, opaquetype): - assert isinstance(opaquetype, lltype.OpaqueType) - self.db = db - self.opaquetype = opaquetype - self.ref = "opaquetype." + opaquetype.tag - - def __str__(self): - return "" %(self.ref,) - - # ______________________________________________________________________ - # main entry points from genllvm - - #def writedatatypedecl(self, codewriter): - # # XXX Dummy - not sure what what we want - # codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *']) - class OpaqueNode(ConstantLLVMNode): def __init__(self, db, value): Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Sun Oct 16 12:26:46 2005 @@ -99,7 +99,6 @@ 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 try: @@ -119,7 +118,6 @@ res_val = self.db.repr_tmpvar() self.codewriter.binaryop('*', res_val, - mult_type, last_val, mult_val) last_val = res_val @@ -157,21 +155,18 @@ def bool_not(self, op): self.codewriter.binaryop('^', self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "true") def int_invert(self, op): self.codewriter.binaryop('^', self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), -1) def uint_invert(self, op): self.codewriter.binaryop('^', self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), str((1L<<32) - 1)) @@ -180,7 +175,6 @@ assert len(op.args) == 2 self.codewriter.binaryop(name, self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), self.db.repr_arg(op.args[1])) @@ -192,7 +186,7 @@ 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) + self.codewriter.binaryop(name, res, c1, c2) def cast_char_to_int(self, op): " works for all casts " @@ -209,17 +203,16 @@ " works for all casts " assert len(op.args) == 1 targetvar = self.db.repr_arg(op.result) - targettype = self.db.repr_arg_type(op.result) + targettype = self.db.repr_concretetype(op.result.concretetype) fromvar = self.db.repr_arg(op.args[0]) - fromtype = self.db.repr_arg_type(op.args[0]) - self.codewriter.comment('next line='+op.opname) + fromtype = self.db.repr_concretetype(op.args[0].concretetype) + self.codewriter.comment('next line=%s, from %s to %s' % (op.opname, fromtype, targettype)) self.codewriter.cast(targetvar, fromtype, fromvar, targettype) same_as = cast_primitive def int_is_true(self, op): self.codewriter.binaryop("!=", self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "0") uint_is_true = int_is_true @@ -227,21 +220,18 @@ def float_is_true(self, op): self.codewriter.binaryop("!=", self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "0.0") def ptr_nonzero(self, op): self.codewriter.binaryop("!=", self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "null") def ptr_iszero(self, op): self.codewriter.binaryop("==", self.db.repr_arg(op.result), - self.db.repr_arg_type(op.args[0]), self.db.repr_arg(op.args[0]), "null") @@ -250,19 +240,12 @@ if arg.concretetype is not lltype.Void] assert len(op_args) >= 1 targetvar = self.db.repr_arg(op.result) - returntype = self.db.repr_arg_type(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:]) - #if self.db.is_function_ptr(op.result): - # returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) + argtypes = [] #self.db.repr_arg_type_multi(op_args[1:]) self.codewriter.call(targetvar,returntype,functionref,argrefs,argtypes) - def last_exception_type_ptr(self, op): - e = self.db.translator.rtyper.getexceptiondata() - lltype_of_exception_type = ('structtype.' + e.lltype_of_exception_type.TO.__name__ + '*') - self.codewriter.load('%'+str(op.result), lltype_of_exception_type, 'last_exception_type') - def invoke(self, op): op_args = [arg for arg in op.args if arg.concretetype is not lltype.Void] @@ -363,38 +346,13 @@ ep.reraise(self.node, self.codewriter) ep.fetch_exceptions(self.codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value) - def malloc_exception(self, op): - arg_type = op.args[0].value - targetvar = self.db.repr_arg(op.result) - type_ = self.db.repr_type(arg_type) - tmpvar1 = self.db.repr_tmpvar() - tmpvar2 = self.db.repr_tmpvar() - tmpvar3 = self.db.repr_tmpvar() - self.codewriter.append('%(tmpvar1)s = getelementptr %(type_)s* null, int 1' % locals()) - self.codewriter.cast(tmpvar2, type_+'*', tmpvar1, 'uint') - self.codewriter.call(tmpvar3, 'sbyte*', 'malloc_exception', [tmpvar2], ['uint']) - self.codewriter.cast(targetvar, 'sbyte*', tmpvar3, type_+'*') - def malloc(self, op): arg_type = op.args[0].value targetvar = self.db.repr_arg(op.result) - type_ = self.db.repr_type(arg_type) + type_ = '' #self.db.repr_type(arg_type) self.codewriter.malloc(targetvar, type_, atomic=arg_type._is_atomic()) - - def malloc_varsize(self, op): - 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 varsized anymore - self.malloc(op) - return - - 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, type_, type_cons, argrefs, argtypes) + malloc_exception = malloc + malloc_varsize = malloc def _getindexhelper(self, name, struct): assert name in list(struct._names) @@ -407,17 +365,16 @@ return index def getfield(self, op): - tmpvar = self.db.repr_tmpvar() - struct, structtype = self.db.repr_argwithtype(op.args[0]) + struct = self.db.repr_arg(op.args[0]) targetvar = self.db.repr_arg(op.result) - targettype = self.db.repr_arg_type(op.result) + targettype = 'undefined' #self.db.repr_arg_type(op.result) if targettype != "void": self.codewriter.append('%s = %s.%s' % (targetvar, struct, op.args[1].value)) #XXX move to codewriter else: self._skipped(op) def getsubstruct(self, op): - struct, structtype = self.db.repr_argwithtype(op.args[0]) + struct = self.db.repr_arg(op.args[0]) #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) @@ -426,19 +383,20 @@ #self.codewriter.getelementptr(targetvar, structtype, struct, ("uint", index)) def setfield(self, op): - struct, structtype = self.db.repr_argwithtype(op.args[0]) - valuevar, valuetype = self.db.repr_argwithtype(op.args[2]) - if valuetype != "void": + struct = self.db.repr_arg(op.args[0]) + valuevar = self.db.repr_arg(op.args[2]) + valuetype = 'undefined' #XXX how to get to this when no longer keep track of type + if valuetype != "void": self.codewriter.append('%s.%s = %s' % (struct, op.args[1].value, valuevar)) #XXX move to codewriter else: self._skipped(op) - + def getarrayitem(self, op): - array, arraytype = self.db.repr_argwithtype(op.args[0]) + array = self.db.repr_arg(op.args[0]) index = self.db.repr_arg(op.args[1]) - indextype = self.db.repr_arg_type(op.args[1]) + #indextype = self.db.repr_arg_type(op.args[1]) targetvar = self.db.repr_arg(op.result) - targettype = self.db.repr_arg_type(op.result) + targettype = 'undefined' #self.db.repr_arg_type(op.result) if targettype != "void": #tmpvar = self.db.repr_tmpvar() #self.codewriter.getelementptr(tmpvar, arraytype, array, @@ -449,19 +407,20 @@ self._skipped(op) def getarraysubstruct(self, op): - array, arraytype = self.db.repr_argwithtype(op.args[0]) + array = self.db.repr_arg(op.args[0]) + arraytype = '' index = self.db.repr_arg(op.args[1]) - indextype = self.db.repr_arg_type(op.args[1]) + indextype = '' #self.db.repr_arg_type(op.args[1]) targetvar = self.db.repr_arg(op.result) self.codewriter.getelementptr(targetvar, arraytype, array, ("uint", 1), (indextype, index)) def setarrayitem(self, op): - array, arraytype = self.db.repr_argwithtype(op.args[0]) + array = self.db.repr_arg(op.args[0]) index = self.db.repr_arg(op.args[1]) - indextype = self.db.repr_arg_type(op.args[1]) + #indextype = self.db.repr_arg_type(op.args[1]) valuevar = self.db.repr_arg(op.args[2]) - valuetype = self.db.repr_arg_type(op.args[2]) + valuetype = 'undefined' #self.db.repr_arg_type(op.args[2]) if valuetype != "void": #tmpvar = self.db.repr_tmpvar() #self.codewriter.getelementptr(tmpvar, arraytype, array, @@ -472,7 +431,7 @@ self._skipped(op) def getarraysize(self, op): - array, arraytype = self.db.repr_argwithtype(op.args[0]) + array = self.db.repr_arg(op.args[0]) #tmpvar = self.db.repr_tmpvar() #self.codewriter.getelementptr(tmpvar, arraytype, array, ("uint", 0)) targetvar = self.db.repr_arg(op.result) Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Sun Oct 16 12:26:46 2005 @@ -2,79 +2,14 @@ from pypy.translator.js.node import LLVMNode, ConstantLLVMNode from pypy.rpython import lltype from pypy.translator.js.log import log - log = log.structnode + def _rename_reserved_keyword(name): if name in 'if then else function for while witch continue break super int bool Array String Struct Number'.split(): name += '_' return name -class StructTypeNode(LLVMNode): - __slots__ = "db struct ref name".split() - - def __init__(self, db, struct): - assert isinstance(struct, lltype.Struct) - self.db = db - self.struct = struct - prefix = 'structtype_' - name = self.struct._name - self.ref = self.make_ref(prefix, name) - self.name = self.ref[len(prefix):] - - 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._fields(): - self.db.prepare_type(field) - - # ______________________________________________________________________ - # main entry points from genllvm - - #def writedatatypedecl(self, codewriter): - # fields_types = [self.db.repr_type(f) for f in self._fields()] - # 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) - prefix = 'new_varsizestruct_' - self.constructor_ref = self.make_ref(prefix, self.name) - self.constructor_decl = "%s * %s(int %%len)" % \ - (self.ref, - self.constructor_ref) - - def __str__(self): - return "" %(self.ref,) - - # ______________________________________________________________________ - # main entry points from genllvm - - #def writedecl(self, codewriter): - # # declaration for constructor - # codewriter.declare(self.constructor_decl) - - def writeimpl(self, codewriter): - log.writeimpl(self.ref) - - # build up a list of indices to get to the last - # var-sized struct (or rather the according array) - indices_to_array = [] - current = self.struct - while isinstance(current, lltype.Struct): - last_pos = len(current._names_without_voids()) - 1 - 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) class StructNode(ConstantLLVMNode): """ A struct constant. Can simply contain @@ -121,9 +56,6 @@ def writedecl(self, codewriter): codewriter.declare(self.ref + ' = new Object()') - #def get_typerepr(self): - # return self.db.repr_type(self.structtype) - def get_childref(self, index): return self.get_ref() #XXX what to do with index? #pos = 0 @@ -150,10 +82,6 @@ self._get_ref_cache = ref return ref - #def get_pbcref(self, toptr): - # """ Returns a reference as used per pbc. """ - # return self.get_ref() - def constantvalue(self): """ Returns the constant representation for this node. """ vars = [] @@ -222,7 +150,3 @@ def get_ref(self): return self.ref - - #def get_pbcref(self, toptr): - # """ Returns a reference as used per pbc. """ - # return self.ref Modified: pypy/dist/pypy/translator/js/test/runtest.py ============================================================================== --- pypy/dist/pypy/translator/js/test/runtest.py (original) +++ pypy/dist/pypy/translator/js/test/runtest.py Sun Oct 16 12:26:46 2005 @@ -21,7 +21,8 @@ a = t.annotate(annotation) a.simplify() t.specialize() - t.backend_optimizations() + t.backend_optimizations(inline_threshold=0, mallocs=False) + #t.backend_optimizations() if view: t.view() self.js = JS(t, function) From arigo at codespeak.net Sun Oct 16 12:52:20 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 16 Oct 2005 12:52:20 +0200 (CEST) Subject: [pypy-svn] r18677 - pypy/dist/pypy/objspace/std Message-ID: <20051016105220.C403427B43@code1.codespeak.net> Author: arigo Date: Sun Oct 16 12:52:19 2005 New Revision: 18677 Modified: pypy/dist/pypy/objspace/std/stringobject.py Log: Obscure change required to catch MemoryError. Catching it in-function doesn't work through the flow object space. Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Sun Oct 16 12:52:19 2005 @@ -855,6 +855,11 @@ str = "".join([s[start + i*step] for i in range(sl)]) return W_StringObject(space, str) +def _makebuf(length): + """This helper needs to be a separate function so that we can safely + catch the MemoryErrors that it raises.""" + return ['\x00'] * length + def mul_string_times(space, w_str, w_times): try: mul = space.int_w(w_times) @@ -867,7 +872,7 @@ return space.wrap("") input_len = len(input) try: - buffer = [' '] * ovfcheck(mul*input_len) + buffer = _makebuf(ovfcheck(mul*input_len)) except (MemoryError,OverflowError,ValueError): # ugh. ValueError is what you get on 64-bit machines for # integers in range(2**31, 2**63). From mwh at codespeak.net Sun Oct 16 12:54:46 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 16 Oct 2005 12:54:46 +0200 (CEST) Subject: [pypy-svn] r18678 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem ootypesystem/test Message-ID: <20051016105446.041E727B43@code1.codespeak.net> Author: mwh Date: Sun Oct 16 12:54:43 2005 New Revision: 18678 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/typesystem.py Log: (mwh, bert, samuele) We didn't have a test that had a variable that potentially contained an instance of either of a base class or its subclass. When we added one, we found a range of subtle problems with lltype-era assumptions in llinterp and other places. OOTypes now has a notion of upcasting and llinterp has a few changes to accomodate this. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sun Oct 16 12:54:43 2005 @@ -124,7 +124,7 @@ def setvar(self, var, val): if var.concretetype != self.llt.Void: - assert var.concretetype == self.llt.typeOf(val) + assert self.llinterpreter.typer.type_system.isCompatibleType(self.llt.typeOf(val), var.concretetype) assert isinstance(var, Variable) self.bindings[var] = val @@ -221,7 +221,7 @@ ophandler = self.getoperationhandler(operation.opname) vals = [self.getval(x) for x in operation.args] # if these special cases pile up, do something better here - if operation.opname == 'cast_pointer': + if operation.opname in ['cast_pointer', 'ooupcast']: vals.insert(0, operation.result.concretetype) retval = ophandler(*vals) self.setvar(operation.result, retval) @@ -641,6 +641,9 @@ assert isinstance(inst, ootype._instance) assert isinstance(message, str) return getattr(inst, message)(*args) + + def op_ooupcast(self, INST, inst): + return ootype.ooupcast(INST, inst) # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sun Oct 16 12:54:43 2005 @@ -962,6 +962,9 @@ " returned: %s,\n" "should have been: %s" % (p, result2, result)) return result + +def isCompatibleType(TYPE1, TYPE2): + return TYPE1 == TYPE2 # FIXME __all__ = ['Array', 'Bool', 'Char', 'ContainerType', 'Float', @@ -974,5 +977,5 @@ 'castable', 'flavored_malloc', 'frozendict', 'functionptr', 'getRuntimeTypeInfo', 'log', 'malloc', 'nullptr', 'opaqueptr', 'operator', 'parentlink', 'py', 'pyobjectptr', 'r_uint', 'runtime_type_info', 'safe_equal', -'saferecursive', 'tlsobject', 'typeOf', 'weakref'] +'saferecursive', 'tlsobject', 'typeOf', 'weakref', 'isCompatibleType'] Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Sun Oct 16 12:54:43 2005 @@ -190,10 +190,7 @@ raise TypeError,"calling %r with wrong argument number: %r" % (self._TYPE, args) for a, ARG in zip(args, self._TYPE.ARGS): - if typeOf(a) != ARG: - if isinstance(ARG, Instance) and isinstance(a, _instance): - if instanceof(a, ARG): - continue + if not isCompatibleType(typeOf(a), ARG): raise TypeError,"calling %r with wrong argument types: %r" % (self._TYPE, args) callb = self._callable if callb is None: @@ -273,3 +270,16 @@ return c c = c._superclass return None + +def isCompatibleType(TYPE1, TYPE2): + if TYPE1 == TYPE2: + return True + if isinstance(TYPE1, Instance) and isinstance(TYPE2, Instance): + return isSubclass(TYPE1, TYPE2) + else: + return False + +def ooupcast(INSTANCE, instance): + assert instanceof(instance, INSTANCE) + return instance + Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sun Oct 16 12:54:43 2005 @@ -3,6 +3,7 @@ getinstancerepr from pypy.rpython.rpbc import getsignature from pypy.rpython.ootypesystem import ootype +from pypy.annotation.pairtype import pairtype CLASSTYPE = ootype.Class @@ -90,3 +91,26 @@ return llops.genop("new", [inputconst(ootype.Void, self.lowleveltype)], self.lowleveltype) + + +class __extend__(pairtype(InstanceRepr, InstanceRepr)): + def convert_from_to((r_ins1, r_ins2), v, llops): + # which is a subclass of which? + if r_ins1.classdef is None or r_ins2.classdef is None: + basedef = None + else: + basedef = r_ins1.classdef.commonbase(r_ins2.classdef) + if basedef == r_ins2.classdef: + # r_ins1 is an instance of the subclass: converting to parent + v = llops.genop('ooupcast', [v], + resulttype = r_ins2.lowleveltype) + return v + elif basedef == r_ins1.classdef: + # r_ins2 is an instance of the subclass: potentially unsafe + # casting, but we do it anyway (e.g. the annotator produces + # such casts after a successful isinstance() check) + v = llops.genop('oodowncast', [v], + resulttype = r_ins2.lowleveltype) + return v + else: + return NotImplemented Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sun Oct 16 12:54:43 2005 @@ -76,6 +76,21 @@ result = interpret(dummyfn, [], type_system='ootype') assert result == 1 + 2 + 3 +def test_polymorphic_field(): + def dummyfn(choosesubclass): + if choosesubclass: + y = Subclass() + y.a = 0 + y.b = 1 + else: + y = EmptyBase() + y.a = 1 + return y.a + result = interpret(dummyfn, [True], type_system='ootype') + assert result == 0 + result = interpret(dummyfn, [False], type_system='ootype') + assert result == 1 + class HasAMethod(object): def f(self): return 1 Modified: pypy/dist/pypy/rpython/typesystem.py ============================================================================== --- pypy/dist/pypy/rpython/typesystem.py (original) +++ pypy/dist/pypy/rpython/typesystem.py Sun Oct 16 12:54:43 2005 @@ -74,6 +74,9 @@ def getconcretetype(self, v): return getattr(v, 'concretetype', lltype.Ptr(lltype.PyObject)) + def isCompatibleType(self, t1, t2): + return lltype.isCompatibleType(t1, t2) + class ObjectOrientedTypeSystem(TypeSystem): name = "ootypesystem" callable_trait = (ootype.StaticMethod, ootype.static_meth) @@ -84,6 +87,9 @@ assert isinstance(ootype.typeOf(obj), ootype.OOType) return obj + def isCompatibleType(self, t1, t2): + return ootype.isCompatibleType(t1, t2) + # All typesystems are singletons LowLevelTypeSystem.instance = LowLevelTypeSystem() ObjectOrientedTypeSystem.instance = ObjectOrientedTypeSystem() From cfbolz at codespeak.net Sun Oct 16 13:10:09 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 16 Oct 2005 13:10:09 +0200 (CEST) Subject: [pypy-svn] r18679 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051016111009.09D8E27B43@code1.codespeak.net> Author: cfbolz Date: Sun Oct 16 13:10:07 2005 New Revision: 18679 Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py pypy/dist/pypy/rpython/l3interp/model.py pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: (pedronis, cfbolz): added call_graph_int + test Modified: pypy/dist/pypy/rpython/l3interp/l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/l3interp.py Sun Oct 16 13:10:07 2005 @@ -6,6 +6,8 @@ pass class LLInterpreter(object): + def __init__(self, globals): + self.globals = globals def eval_graph_int(self, graph, args): frame = LLFrame(graph, self) returnlink = frame.eval(args) @@ -20,13 +22,14 @@ def eval(self, int_values): link = self.graph.startlink self.copy_startlink_vars(link, int_values) - while type(link) is model.Link: + while not link.stop_graph_evaluation: link = self.eval_block(link.target) self.copy_link_vars(link) return link def eval_block(self, block): for op in block.operations: +# print op.opimpl, op.result, op.args, self.int_vars op.opimpl(self, op.result, op.args) exitswitch = block.exitswitch if exitswitch >= 0: @@ -35,6 +38,7 @@ return block.exits[0] def copy_startlink_vars(self, link, int_values): +# print "copy_startlink_vars", int_values, link.move_int_registers if link.move_int_registers is None: return for i in range(0, len(link.move_int_registers), 2): @@ -43,6 +47,7 @@ self.set_int(target, int_values[source]) def copy_link_vars(self, link): +# print "copy_link_vars", link.move_int_registers, self.int_vars if link.move_int_registers is None: return for i in range(0, len(link.move_int_registers), 2): @@ -67,3 +72,9 @@ def op_int_is_true(self, result, args): int1 = self.get_int(args[0]) self.set_int(result, bool(int1)) + + def op_call_graph_int(self, result, args): + graph = self.interp.globals.graphs[args[0]] + concrete_args = [self.get_int(arg) for arg in args[1:]] + r = self.interp.eval_graph_int(graph, concrete_args) + self.set_int(result, r) Modified: pypy/dist/pypy/rpython/l3interp/model.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/model.py (original) +++ pypy/dist/pypy/rpython/l3interp/model.py Sun Oct 16 13:10:07 2005 @@ -95,6 +95,7 @@ self.result = result # resulting variable class Link(object): + stop_graph_evaluation = False def __init__(self, target, exitcase=None): self.target = target # target is a Block self.exitcase = exitcase # NULL for non-exceptional case @@ -102,6 +103,7 @@ self.move_int_registers = None class ReturnLink(Link): + stop_graph_evaluation = True def __init__(self, return_val=0, exitcase=None): Link.__init__(self, None, exitcase) if return_val != 0: Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sun Oct 16 13:10:07 2005 @@ -25,7 +25,7 @@ graph.set_constants_int([3, 4]) g = model.Globals() g.graphs = [graph] - interp = l3interp.LLInterpreter() + interp = l3interp.LLInterpreter(g) return interp.eval_graph_int(graph, []) def test_very_simple(): @@ -50,7 +50,7 @@ graph.set_constants_int([4]) g = model.Globals() g.graphs = [graph] - interp = l3interp.LLInterpreter() + interp = l3interp.LLInterpreter(g) return interp.eval_graph_int(graph, [number]) def test_simple(): @@ -78,7 +78,7 @@ graph.set_constants_int([1, 2]) g = model.Globals() g.graphs = [graph] - interp = l3interp.LLInterpreter() + interp = l3interp.LLInterpreter(g) return interp.eval_graph_int(graph, [number]) def test_branch(): @@ -92,3 +92,46 @@ assert fn(4) == 2 assert fn(0) == 1 +#---------------------------------------------------------------------- + +def eval_call(number): + #XXX uh: this isn't funny anymore + #def g(x): + # return x + 1 + #def f(x): + # return g(x) + 2 + op_g = model.Operation(l3interp.LLFrame.op_int_add, 1, [0, -1]) + op_f = model.Operation(l3interp.LLFrame.op_int_add, 2, [1, -1]) + call_op = model.Operation(l3interp.LLFrame.op_call_graph_int, 1, [0, 0]) + returnlink_g = model.ReturnLink(1) + returnlink_f = model.ReturnLink(2) + block_g = model.Block(model.ONE_EXIT, [returnlink_g]) + block_g.operations.append(op_g) + startlink_g = model.StartLink(target=block_g) + startlink_g.move_int_registers = [0, 0] + graph_g = model.Graph("g", startlink_g) + graph_g.set_constants_int([1]) + + block_f = model.Block(model.ONE_EXIT, [returnlink_f]) + block_f.operations.extend([call_op, op_f]) + startlink_f = model.StartLink(target=block_f) + startlink_f.move_int_registers = [0, 0] + graph_f = model.Graph("f", startlink_f) + graph_f.set_constants_int([2]) + g = model.Globals() + g.graphs = [graph_g, graph_f] + interp = l3interp.LLInterpreter(g) + return interp.eval_graph_int(graph_f, [number]) + +def test_call(): + result = eval_call(4) + assert result == 7 + result = eval_call(0) + assert result == 3 + +def test_call_translated(): + fn = translate(eval_call, [int]) + assert fn(4) == 7 + assert fn(0) == 3 + + From mwh at codespeak.net Sun Oct 16 13:34:01 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 16 Oct 2005 13:34:01 +0200 (CEST) Subject: [pypy-svn] r18680 - pypy/dist/pypy/annotation Message-ID: <20051016113401.5B72027B3D@code1.codespeak.net> Author: mwh Date: Sun Oct 16 13:34:00 2005 New Revision: 18680 Modified: pypy/dist/pypy/annotation/classdef.py Log: more grammar like Modified: pypy/dist/pypy/annotation/classdef.py ============================================================================== --- pypy/dist/pypy/annotation/classdef.py (original) +++ pypy/dist/pypy/annotation/classdef.py Sun Oct 16 13:34:00 2005 @@ -19,7 +19,7 @@ # classdef of A or a parent class of A has an Attribute object corresponding # to that name. # -# (I) if B is a subclass of A, then they don't have both an Attribute for the +# (I) if B is a subclass of A, then they don't both have an Attribute for the # same name. (All information from B's Attribute must be merged into A's.) # # Additionally, each ClassDef records an 'attr_sources': it maps attribute From bert at codespeak.net Sun Oct 16 14:07:29 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Sun, 16 Oct 2005 14:07:29 +0200 (CEST) Subject: [pypy-svn] r18681 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051016120729.0379727B3D@code1.codespeak.net> Author: bert Date: Sun Oct 16 14:07:29 2005 New Revision: 18681 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: (boria, mwh, bert, samuele, arigo) * ootype: test and support for overridden methods * llinterp: interpret "oosend" rather than just calling the method, implement "oodowncast" Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Sun Oct 16 14:07:29 2005 @@ -221,7 +221,7 @@ ophandler = self.getoperationhandler(operation.opname) vals = [self.getval(x) for x in operation.args] # if these special cases pile up, do something better here - if operation.opname in ['cast_pointer', 'ooupcast']: + if operation.opname in ['cast_pointer', 'ooupcast', 'oodowncast']: vals.insert(0, operation.result.concretetype) retval = ophandler(*vals) self.setvar(operation.result, retval) @@ -640,11 +640,17 @@ def op_oosend(self, message, inst, *args): assert isinstance(inst, ootype._instance) assert isinstance(message, str) - return getattr(inst, message)(*args) + bm = getattr(inst, message) + m = bm.meth + m._checkargs(args) + return self.op_direct_call(m, inst, *args) def op_ooupcast(self, INST, inst): return ootype.ooupcast(INST, inst) + def op_oodowncast(self, INST, inst): + return ootype.oodowncast(INST, inst) + # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help # for failing tests Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Sun Oct 16 14:07:29 2005 @@ -283,3 +283,7 @@ assert instanceof(instance, INSTANCE) return instance +def oodowncast(INSTANCE, instance): + assert instanceof(instance, INSTANCE) + return instance + Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sun Oct 16 14:07:29 2005 @@ -48,20 +48,20 @@ methods = {} baseInstance = self.lowleveltype._superclass - for name, attrdef in attrs: - if attrdef.readonly: - # if the following line suffers an AttributeError, - # maybe the attr is actually not a method. - assert len(attrdef.s_value.prebuiltinstances) == 1, 'no support for overridden methods yet' - # XXX following might not always succeed - impl = self.classdef.cls.__dict__[name] - - f, inputs, ret = getsignature(self.rtyper, impl) - M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) - m = ootype.meth(M, _name=name, _callable=impl) - - methods[name] = m - + for classdef in self.classdef.getmro(): + attrs = classdef.attrs.items() + for name, attrdef in attrs: + if attrdef.readonly: + try: + impl = self.classdef.cls.__dict__[name] + except KeyError: + pass + else: + f, inputs, ret = getsignature(self.rtyper, impl) + M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) + m = ootype.meth(M, _name=name, _callable=impl) + methods[name] = m + ootype.addMethods(self.lowleveltype, methods) def rtype_getattr(self, hop): Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sun Oct 16 14:07:29 2005 @@ -101,3 +101,19 @@ return inst.f() result = interpret(dummyfn, [], type_system='ootype') assert result == 1 + +class OverridesAMethod(HasAMethod): + def f(self): + return 2 + +def test_override(): + def dummyfn(flag): + if flag: + inst = HasAMethod() + else: + inst = OverridesAMethod() + return inst.f() + result = interpret(dummyfn, [True], type_system='ootype') + assert result == 1 + result = interpret(dummyfn, [False], type_system='ootype') + assert result == 2 From cfbolz at codespeak.net Sun Oct 16 14:07:33 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 16 Oct 2005 14:07:33 +0200 (CEST) Subject: [pypy-svn] r18682 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051016120733.6472827B46@code1.codespeak.net> Author: cfbolz Date: Sun Oct 16 14:07:31 2005 New Revision: 18682 Modified: pypy/dist/pypy/rpython/l3interp/model.py pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Log: (cfbolz, pedronis): remove the arguments exitswitch and exits from the Block constructor and rather build this incrementally. This is needed for dependency reasons in the graph converter. Modified: pypy/dist/pypy/rpython/l3interp/model.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/model.py (original) +++ pypy/dist/pypy/rpython/l3interp/model.py Sun Oct 16 14:07:31 2005 @@ -114,11 +114,11 @@ pass class Block(object): - def __init__(self, exitswitch, exits): - self.operations = [] # list of Operations - self.exitswitch = exitswitch # positives are variables - # negatives see above - self.exits = exits # list of Links + def __init__(self): + self.operations = [] # list of Operations + self.exitswitch = 0 # positives are variables + # negatives see above + self.exits = [] # list of Links class Graph(object): def __init__(self, name, startlink): @@ -130,19 +130,6 @@ def set_constants_int(self, constants): self.constants_int = constants - def blocklist(self): - result = [] - pending = [self.startblock] - seen = {} - while len(pending): - block = pending.pop() - if block in seen: - continue - result.append(block) - for i in range(len(block.exits)): - pending.append(block.exits[i].target) - return result - class Globals(object): def __init__(self): self.graphs = [] # list of Graphs Modified: pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py (original) +++ pypy/dist/pypy/rpython/l3interp/test/test_l3interp.py Sun Oct 16 14:07:31 2005 @@ -18,7 +18,9 @@ # return 3 + 4 op = model.Operation(l3interp.LLFrame.op_int_add, 0, [-1, -2]) returnlink = model.ReturnLink() - block = model.Block(model.ONE_EXIT, [returnlink]) + block = model.Block() + block.exitswitch = model.ONE_EXIT + block.exits = [returnlink] block.operations.append(op) startlink = model.Link(block, []) graph = model.Graph("testgraph", startlink) @@ -42,7 +44,9 @@ # return x + 4 op = model.Operation(l3interp.LLFrame.op_int_add, 1, [0, -1]) returnlink = model.ReturnLink(return_val=1) - block = model.Block(model.ONE_EXIT, [returnlink]) + block = model.Block() + block.exitswitch = model.ONE_EXIT + block.exits = [returnlink] block.operations.append(op) startlink = model.Link(target=block) startlink.move_int_registers = [0, 0] @@ -70,7 +74,9 @@ op = model.Operation(l3interp.LLFrame.op_int_is_true, 1, [0]) returnlink1 = model.ReturnLink(-1) returnlink2 = model.ReturnLink(-2) - block = model.Block(1, [returnlink1, returnlink2]) + block = model.Block() + block.exitswitch = 1 + block.exits = [returnlink1, returnlink2] block.operations.append(op) startlink = model.Link(target=block) startlink.move_int_registers = [0, 0] @@ -105,14 +111,18 @@ call_op = model.Operation(l3interp.LLFrame.op_call_graph_int, 1, [0, 0]) returnlink_g = model.ReturnLink(1) returnlink_f = model.ReturnLink(2) - block_g = model.Block(model.ONE_EXIT, [returnlink_g]) + block_g = model.Block() + block_g.exitswitch = model.ONE_EXIT + block_g.exits = [returnlink_g] block_g.operations.append(op_g) startlink_g = model.StartLink(target=block_g) startlink_g.move_int_registers = [0, 0] graph_g = model.Graph("g", startlink_g) graph_g.set_constants_int([1]) - block_f = model.Block(model.ONE_EXIT, [returnlink_f]) + block_f = model.Block() + block_f.exitswitch = model.ONE_EXIT + block_f.exits = [returnlink_f] block_f.operations.extend([call_op, op_f]) startlink_f = model.StartLink(target=block_f) startlink_f.move_int_registers = [0, 0] From arigo at codespeak.net Sun Oct 16 14:11:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 16 Oct 2005 14:11:27 +0200 (CEST) Subject: [pypy-svn] r18683 - in pypy/dist/pypy: objspace/flow rpython rpython/test translator/c/test Message-ID: <20051016121127.0C76B27B3E@code1.codespeak.net> Author: arigo Date: Sun Oct 16 14:11:25 2005 New Revision: 18683 Modified: pypy/dist/pypy/objspace/flow/objspace.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/translator/c/test/test_annotated.py Log: * flow space now supports raising IndexError in setitem * minor changes in rlist.delitem's bound checking. Modified: pypy/dist/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/objspace.py (original) +++ pypy/dist/pypy/objspace/flow/objspace.py Sun Oct 16 14:11:25 2005 @@ -353,7 +353,8 @@ return self.w_None except UnwrapException: pass - return self.do_operation('setitem', w_obj, w_key, w_val) + return self.do_operation_with_implicit_exceptions('setitem', w_obj, + w_key, w_val) def call_args(self, w_callable, args): try: @@ -456,9 +457,7 @@ implicit_exceptions[name+"_ovf"] = lis for _err in IndexError, KeyError: - _add_exceptions("""getitem""", _err) - _add_exceptions("""delitem""", _err) - # no implicit exceptions for setitem + _add_exceptions("""getitem setitem delitem""", _err) for _name in 'getattr', 'delattr': _add_exceptions(_name, AttributeError) for _name in 'iter', 'coerce': Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Sun Oct 16 14:11:25 2005 @@ -535,7 +535,7 @@ def ll_delitem_nonneg(func, l, index): length = l.length - if func is dum_checkidx and (index < 0 or index >= length): + if func is dum_checkidx and (index >= length): raise IndexError newlength = length - 1 j = index @@ -551,9 +551,12 @@ _ll_list_resize_le(l, newlength) def ll_delitem(func, l, i): + length = l.length if i < 0: - i += l.length - ll_delitem_nonneg(func, l, i) + i += length + if func is dum_checkidx and (i < 0 or i >= length): + raise IndexError + ll_delitem_nonneg(dum_nocheck, l, i) def ll_concat(l1, l2): len1 = l1.length 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 Sun Oct 16 14:11:25 2005 @@ -429,6 +429,10 @@ def fn(i): l = [5, 8, 3] try: + l[i] = 99 + except IndexError: + pass + try: del l[i] except IndexError: pass Modified: pypy/dist/pypy/translator/c/test/test_annotated.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_annotated.py (original) +++ pypy/dist/pypy/translator/c/test/test_annotated.py Sun Oct 16 14:11:25 2005 @@ -199,3 +199,17 @@ assert fn(65) == 65 assert fn(-12) == -42 assert fn(sys.maxint) == -42 + + def test_list_indexerror(self): + def f(i=int): + lst = [123, 456] + try: + lst[i] = 789 + except IndexError: + return 42 + return lst[0] + fn = self.getcompiled(f) + assert fn(1) == 123 + assert fn(2) == 42 + assert fn(-2) == 789 + assert fn(-3) == 42 From mwh at codespeak.net Sun Oct 16 14:46:10 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 16 Oct 2005 14:46:10 +0200 (CEST) Subject: [pypy-svn] r18684 - pypy/dist/pypy/rpython Message-ID: <20051016124610.94B6827B42@code1.codespeak.net> Author: mwh Date: Sun Oct 16 14:46:09 2005 New Revision: 18684 Modified: pypy/dist/pypy/rpython/typesystem.py Log: remove an obsolete FIXME Modified: pypy/dist/pypy/rpython/typesystem.py ============================================================================== --- pypy/dist/pypy/rpython/typesystem.py (original) +++ pypy/dist/pypy/rpython/typesystem.py Sun Oct 16 14:46:09 2005 @@ -81,8 +81,6 @@ name = "ootypesystem" callable_trait = (ootype.StaticMethod, ootype.static_meth) - # FIXME rclass - def deref(self, obj): assert isinstance(ootype.typeOf(obj), ootype.OOType) return obj From mwh at codespeak.net Sun Oct 16 14:48:17 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 16 Oct 2005 14:48:17 +0200 (CEST) Subject: [pypy-svn] r18685 - pypy/dist/pypy/rpython/ootypesystem Message-ID: <20051016124817.4511D27B42@code1.codespeak.net> Author: mwh Date: Sun Oct 16 14:48:16 2005 New Revision: 18685 Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py Log: remove another obsolete FIXME Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sun Oct 16 14:48:16 2005 @@ -33,8 +33,6 @@ self.allmethods = {} def _setup_repr(self): - # FIXME methods - fields = {} attrs = self.classdef.attrs.items() From cfbolz at codespeak.net Sun Oct 16 14:51:42 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Sun, 16 Oct 2005 14:51:42 +0200 (CEST) Subject: [pypy-svn] r18686 - in pypy/dist/pypy/rpython/l3interp: . test Message-ID: <20051016125142.950DA27B42@code1.codespeak.net> Author: cfbolz Date: Sun Oct 16 14:51:40 2005 New Revision: 18686 Added: pypy/dist/pypy/rpython/l3interp/convertgraph.py pypy/dist/pypy/rpython/l3interp/test/test_convert.py Log: (cfbolz and bits of pedronis and valentino): start of a graph converter, that can convert very simple graphs + test Added: pypy/dist/pypy/rpython/l3interp/convertgraph.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/l3interp/convertgraph.py Sun Oct 16 14:51:40 2005 @@ -0,0 +1,86 @@ +from pypy.rpython.l3interp import model +from pypy.rpython.l3interp import l3interp +from pypy.objspace.flow import model as flowmodel + +def convert(t): + cvter = LL2L3Converter(t) + return cvter.globals + +class LL2L3Converter(object): + def __init__(self, t): + self.translator = t + self.globals = model.Globals() + self.convert_graph(t.getflowgraph()) + + def convert_graph(self, graph): + graph_cvter = LL2L3GraphConverter(graph, self) + l3graph = graph_cvter.l3graph + self.globals.graphs.append(l3graph) + return l3graph + +class LL2L3GraphConverter(object): + def __init__(self, graph, cvter): + self.cvter = cvter + self.graph = graph + self.blocks_ll2l3 = {} + self.constants_to_index = {} + self.constants = [] + startlink = self.convert_startlink(graph.startblock) + self.l3graph = model.Graph(graph.name, startlink) + self.l3graph.constants_int = self.constants + + def convert_startlink(self, block): + var_to_register = dict([(var, i) + for i, var in enumerate(block.inputargs)]) + target = self.convert_block(block, var_to_register) + startlink = model.Link(target) + startlink.move_int_register = [i // 2 + for i in range(len(block.inputargs) * 2)] + return startlink + + def convert_block(self, block, var_to_register): + if block in self.blocks_ll2l3: + return self.blocks_ll2l3[block] + def get_reg_number(var): + if var not in var_to_register: + var_to_register[var] = len(var_to_register) + return var_to_register[var] + l3ops = [] + for op in block.operations: + l3ops.append(self.convert_op(op, get_reg_number)) + assert block.exitswitch is None + l3block = model.Block() + self.blocks_ll2l3[block] = l3block + l3block.exitswitch = model.ONE_EXIT + l3block.exits = [self.convert_link(block.exits[0], var_to_register)] + l3block.operations = l3ops + return l3block + + def convert_link(self, link, var_to_register): + if link.target is self.graph.returnblock: + l3link = model.ReturnLink(var_to_register[link.args[0]]) + return l3link + assert 0, "not yet implemented" + + def convert_op(self, op, get_reg_number): + c_op = getattr(self, "op_" + op.opname, None) + if c_op is not None: + return c_op(op, get_reg_number) + l3args = [] + for arg in op.args: + if isinstance(arg, flowmodel.Variable): + l3args.append(get_reg_number(arg)) + else: + l3args.append(self.convert_const(arg)) + l3op = model.Operation(getattr(l3interp.LLFrame, "op_" + op.opname), + get_reg_number(op.result), l3args) + return l3op + + def convert_const(self, arg): + arg = int(arg.value) + if arg in self.constants_to_index: + return self.constants_to_index[arg] + index = len(self.constants) + self.constants.append(arg) + self.constants_to_index[arg] = index + return ~index Added: pypy/dist/pypy/rpython/l3interp/test/test_convert.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/l3interp/test/test_convert.py Sun Oct 16 14:51:40 2005 @@ -0,0 +1,14 @@ +from pypy.rpython.l3interp import convertgraph, l3interp +from pypy.translator.translator import Translator + +def test_convert_add(): + def f(x): + return x + 4 + t = Translator(f) + t.annotate([int]) + t.specialize() + globals = convertgraph.convert(t) + interp = l3interp.LLInterpreter(globals) + graph = globals.graphs[0] + result = interp.eval_graph_int(graph, [0]) + assert result == 4 From afa at codespeak.net Sun Oct 16 15:01:54 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sun, 16 Oct 2005 15:01:54 +0200 (CEST) Subject: [pypy-svn] r18687 - pypy/dist/pypy/translator/c/src Message-ID: <20051016130154.5ECF727B45@code1.codespeak.net> Author: afa Date: Sun Oct 16 15:01:45 2005 New Revision: 18687 Modified: pypy/dist/pypy/translator/c/src/ll__socket.h pypy/dist/pypy/translator/c/src/thread_nt.h Log: Fix socket module compilation on windows Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Sun Oct 16 15:01:45 2005 @@ -1,9 +1,8 @@ #ifdef MS_WINDOWS - #include - #include +# pragma comment(lib, "ws2_32.lib") #else - #include +# include #endif int LL__socket_ntohs(int htons); 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 Sun Oct 16 15:01:45 2005 @@ -4,6 +4,10 @@ /* Fast NonRecursiveMutex support by Yakov Markovitch, markovitch at iso.ru */ /* Eliminated some memory leaks, gsw at agere.com */ +/* Windows.h includes winsock.h, but the socket module needs */ +/* winsock2.h. So I include it before. Ugly. */ +#include + #include #include #include From tismer at codespeak.net Sun Oct 16 15:25:13 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 16 Oct 2005 15:25:13 +0200 (CEST) Subject: [pypy-svn] r18688 - pypy/dist/pypy/translator/locality Message-ID: <20051016132513.04F1327B45@code1.codespeak.net> Author: tismer Date: Sun Oct 16 15:25:11 2005 New Revision: 18688 Added: pypy/dist/pypy/translator/locality/calltree.py (contents, props changed) pypy/dist/pypy/translator/locality/projection.py (contents, props changed) Modified: pypy/dist/pypy/translator/locality/simulation.py Log: checking in, incomplete so far but quite far. Added: pypy/dist/pypy/translator/locality/calltree.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/locality/calltree.py Sun Oct 16 15:25:11 2005 @@ -0,0 +1,66 @@ +""" + +CallTree + +An approach to do static call analysis in the PyPy backend +to produce a somewhat locality-of-reference optimized +ordering of the function objects in the generated source. + +In extent to that, it is planned to produce a non-optimized +binary from instrumented source code, run some sample +applications and optimize according to transition statistics. +This step will only be done if the first approach shows any +improvement. + +Sketch of the algorithm: +------------------------ +In a first pass, we inspect all function nodes for direct_call +opcodes and record the callees, if they are constants. +(Variables will later be tried to find out by re-using the +information in the translator). + +We then run a simulation of calls. +See pypy/translator/locality/simulation.py. + +After that, a poly-dimensional model is computed and morphed +into a one-dimensional ordering. +See pypy/translator/locality/projection.py. +""" + +from pypy.objspace.flow.model import Variable, Constant + +class CallTree: + def __init__(self, funcnodes): + self.nodes = funcnodes + self.graphs2nodes = self._build_graph2nodes() + self.calls = {} + for node in self.nodes: + self.calls[node] = self.find_callees(node) + + def _build_graph2nodes(self): + dic = {} + for node in self.nodes: + dic[node.obj.graph] = node + return dic + + def find_callees(self, node): + graph = node.obj.graph + res = [] + for block in graph.iterblocks(): + for op in block.operations: + if op.opname == 'direct_call': + fnarg = op.args[0] + if isinstance(fnarg, Constant): + fnptr = fnarg.value + fn = fnptr._obj + graph = fn.graph + try: + callednode = self.graphs2nodes[graph] + except KeyError: + print "No node found for graph %s" % graph.name + continue + else: + res.append(callednode) + else: + print "Node %s calls Variable %s" % (node, fnarg) + return res Added: pypy/dist/pypy/translator/locality/projection.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/locality/projection.py Sun Oct 16 15:25:11 2005 @@ -0,0 +1,73 @@ +""" + +Turning function dependencies into linear order +----------------------------------------------- + +The purpose of this module is to calculate a good linear +ordering of functions, according to call transition +statistics. + +Every node has some connections to other nodes, expressed +in terms of transition frequencies. As a starting point, +one could assign every node its own dimension. All transitions +would therefore be orthogonal to each other. The resulting +vector space would be quite huge. + +Instead, we use a different approach: + +For a node having t transitions, we order the transitions +by decreasing frequencies. The initial position of each +node is this t-dimensional vector. + +The distance between two nodes along a transition is the +Euclidean distance of the intersecion of the nodes dimensions. +The transition frequencies define a weight for each transition. +The weighted distance between two nodes +""" + +from pypy.translator.locality.simulation import DemoNode, DemoSim +from math import sqrt + +class SpaceNode: + def __init__(self, node): + self.func = node.func + self.name = node.name + + def setup(self, relations, weights): + self.relations = relations + self.weights = weights + self.position = weights[:] # just anything to start with + + def distance(self, other): + # using the nice property of zip to give the minimum length + dist = 0.0 + for x1, x2 in zip(self.position, other.position): + d = x2 - x1 + dist += d * d + return sqrt(dist) + + def lonelyness(self): + # get the sum of weighted distances + lonely = 0.0 + for weight, relative in zip(self.weights, self.relations): + lonely += weight * self.distance(relative) + return lonely + + def corrvector(self): + pass # XXX continue here + +class SpaceGraph: + def __init__(self, simgraph): + mapping = {} + for simnode in simgraph.nodes: + mapping[simnode] = SpaceNode(simnode) + self.nodes = [mapping[simnode] for simnode in simgraph.nodes] + for simnode in simgraph.nodes: + relations, weights = simnode.get_relations() + relations = [mapping[rel] for rel in relations] + node = mapping[simnode] + node.setup(relations, weights) + +if __name__ == '__main__': + from pypy.translator.locality.simulation import test + g = SpaceGraph(test()) Modified: pypy/dist/pypy/translator/locality/simulation.py ============================================================================== --- pypy/dist/pypy/translator/locality/simulation.py (original) +++ pypy/dist/pypy/translator/locality/simulation.py Sun Oct 16 15:25:11 2005 @@ -26,8 +26,20 @@ self.func = func self.name = self._get_name(func) self.callees = [] + self._callers = None # computed self.calls = 0 + def __repr__(self): + return '(%s)' % self.name + + def __cmp__(self, other): + if isinstance(other, self.__class__): + return cmp(self.name, other.name) + return cmp(id(self), id(other)) + + def __hash__(self): + return id(self) + def _get_name(self, func): # to be overridden return func.__name__ @@ -49,6 +61,28 @@ def simulate_call(self, weight=1): self.calls += weight + # calls and returns are symmetric. We provide a callers + # interface that is computed on demand. + + def _get_callers(self): + if not self.sim._callers_computed: + self.sim._compute_callers() + return self.callers + callers = property(_get_callers) + + def get_relations(self): + # get callees and callers with frequency, ordered + # by decreasing frequency and then by name. + ret = [] + for node in self.callees: + freq = self.sim.transitions[ (self, node) ] + ret.append( (-freq, node) ) + for node in self.callers: + freq = self.sim.transitions[ (node, self) ] + ret.append( (-freq, node) ) + ret.sort() + freqs, nodes = zip(*ret) + return nodes, [-freq for freq in freqs] class DemoSim: def __init__(self, funcnodes, nodefactory=DemoNode): @@ -67,6 +101,7 @@ callee = name2node[name] node.callees.append(callee) self.transitions[ (node, callee) ] = 0 + self._callers_computed = False def _find_names_width(self): n = 0 @@ -78,6 +113,7 @@ self.transitions[ (caller, callee) ] += weight def run(self, reps=1, root=0): + self._callers_computed = False self.repetitions_per_call = reps root = self.nodes[root] root.call() @@ -113,6 +149,7 @@ # the transitions in a weighted manner. # this allows us to handle recursions as well. # first, stimulate nodes if no transitions are pending + self._callers_computed = False if not self.pending: if root is not None: startnodes = [self.nodes[root]] @@ -135,6 +172,17 @@ while self.pending: self.simulate(call_prob) + def _compute_callers(self): + nodes = {} + for node in self.nodes: + nodes[node] = node + node.callers = [] + returns = [ (callee, caller) + for caller, callee in self.transitions.keys()] + returns.sort() + for callee, caller in returns: + nodes[callee].callers.append(caller) + # sample functions for proof of correctness def test(debug=False): @@ -157,6 +205,7 @@ sim.sim_all(prob) state2 = sim.get_state() assert state1 == state2 + return sim if __name__ == '__main__': test() From bert at codespeak.net Sun Oct 16 15:33:16 2005 From: bert at codespeak.net (bert at codespeak.net) Date: Sun, 16 Oct 2005 15:33:16 +0200 (CEST) Subject: [pypy-svn] r18689 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051016133316.C6CD327B45@code1.codespeak.net> Author: bert Date: Sun Oct 16 15:33:16 2005 New Revision: 18689 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: (bert, samuele, arigo) * prebuilt instances Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Sun Oct 16 15:33:16 2005 @@ -115,6 +115,14 @@ return meth + def _allfields(self): + if self._superclass is None: + all = {} + else: + all = self._superclass._allfields() + all.update(self._fields) + return all + class StaticMethod(OOType): def __init__(self, args, result): Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Sun Oct 16 15:33:16 2005 @@ -24,21 +24,31 @@ def __init__(self, rtyper, classdef, does_need_gc=True): AbstractInstanceRepr.__init__(self, rtyper, classdef) + self.baserepr = None b = self.classdef.basedef if b is not None: - b = getinstancerepr(rtyper, b).lowleveltype + self.baserepr = getinstancerepr(rtyper, b) + b = self.baserepr.lowleveltype self.lowleveltype = ootype.Instance(classdef.cls.__name__, b, {}, {}) self.prebuiltinstances = {} # { id(x): (x, _ptr) } - self.allmethods = {} + self.object_type = self.lowleveltype def _setup_repr(self): + if self.baserepr is not None: + self.allfields = self.baserepr.allfields.copy() + else: + self.allfields = {} + self.allmethods = {} + fields = {} attrs = self.classdef.attrs.items() for name, attrdef in attrs: if not attrdef.readonly: - oot = self.rtyper.getrepr(attrdef.s_value).lowleveltype + repr = self.rtyper.getrepr(attrdef.s_value) + self.allfields[name] = repr + oot = repr.lowleveltype fields[name] = oot ootype.addFields(self.lowleveltype, fields) @@ -63,14 +73,16 @@ ootype.addMethods(self.lowleveltype, methods) def rtype_getattr(self, hop): + vlist = hop.inputargs(self, ootype.Void) attr = hop.args_s[1].const s_inst = hop.args_s[0] meth = self.lowleveltype._lookup(attr) if meth is not None: - # just return instance - will be handled by simple_call - return hop.inputarg(hop.r_result, arg=0) + # special case for methods: represented as their 'self' only + # (see MethodsPBCRepr) + return hop.r_result.get_method_from_instance(self, vlist[0], + hop.llops) self.lowleveltype._check_field(attr) - vlist = hop.inputargs(self, ootype.Void) return hop.genop("oogetfield", vlist, resulttype = hop.r_result.lowleveltype) @@ -80,9 +92,33 @@ vlist = hop.inputargs(self, ootype.Void, hop.args_r[2]) return hop.genop('oosetfield', vlist) - def convert_const(self): - # FIXME - pass + def convert_const(self, value): + if value is None: + return null(self.lowleveltype) + try: + classdef = self.rtyper.annotator.getuserclasses()[value.__class__] + except KeyError: + raise TyperError("no classdef: %r" % (value.__class__,)) + if classdef != self.classdef: + # if the class does not match exactly, check that 'value' is an + # instance of a subclass and delegate to that InstanceRepr + if classdef is None: + raise TyperError("not implemented: object() instance") + if classdef.commonbase(self.classdef) != self.classdef: + raise TyperError("not an instance of %r: %r" % ( + self.classdef.cls, value)) + rinstance = getinstancerepr(self.rtyper, classdef) + result = rinstance.convert_const(value) + return ootype.ooupcast(self.lowleveltype, result) + # common case + try: + return self.prebuiltinstances[id(value)][1] + except KeyError: + self.setup() + result = ootype.new(self.object_type) + self.prebuiltinstances[id(value)] = value, result + self.initialize_prebuilt_instance(value, result) + return result def new_instance(self, llops): """Build a new instance, without calling __init__.""" @@ -90,6 +126,23 @@ return llops.genop("new", [inputconst(ootype.Void, self.lowleveltype)], self.lowleveltype) + def initialize_prebuilt_instance(self, value, result): + # then add instance attributes from this level + for name, (oot, default) in self.lowleveltype._allfields().items(): + if oot is ootype.Void: + llattrvalue = None + elif name == '_hash_cache_': # hash() support + llattrvalue = hash(value) + else: + try: + attrvalue = getattr(value, name) + except AttributeError: + warning("prebuilt instance %r has no attribute %r" % ( + value, name)) + continue + llattrvalue = self.allfields[name].convert_const(attrvalue) + setattr(result, name, llattrvalue) + class __extend__(pairtype(InstanceRepr, InstanceRepr)): def convert_from_to((r_ins1, r_ins2), v, llops): Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Sun Oct 16 15:33:16 2005 @@ -117,3 +117,15 @@ assert result == 1 result = interpret(dummyfn, [False], type_system='ootype') assert result == 2 + +class HasAField(object): + def f(self): + return self.a + +def test_prebuilt_instance(): + inst = HasAField() + inst.a = 3 + def dummyfn(): + return inst.f() + result = interpret(dummyfn, [], type_system='ootype') + assert result == 3 From afa at codespeak.net Sun Oct 16 16:52:32 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sun, 16 Oct 2005 16:52:32 +0200 (CEST) Subject: [pypy-svn] r18690 - pypy/dist/pypy/translator/c/test Message-ID: <20051016145232.4F93B27B43@code1.codespeak.net> Author: afa Date: Sun Oct 16 16:52:27 2005 New Revision: 18690 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: changed test to work when python is not in the PATH 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 Oct 16 16:52:27 2005 @@ -1,6 +1,6 @@ import autopath import py -import os, time +import os, time, sys from pypy.tool.udir import udir from pypy.translator.c.test.test_genc import compile from pypy.translator.c.extfunc import EXTERNALS @@ -438,7 +438,8 @@ # ____________________________________________________________ def _real_getenv(var): - cmd = '''python -c "import os; x=os.environ.get('%s'); print (x is None) and 'F' or ('T'+x)"''' % var + cmd = '''%s -c "import os; x=os.environ.get('%s'); print (x is None) and 'F' or ('T'+x)"''' % ( + sys.executable, var) g = os.popen(cmd, 'r') output = g.read().strip() g.close() @@ -450,7 +451,7 @@ raise ValueError, 'probing for env var returned %r' % (output,) def _real_envkeys(): - cmd = '''python -c "import os; print os.environ.keys()"''' + cmd = '''%s -c "import os; print os.environ.keys()"''' % sys.executable g = os.popen(cmd, 'r') output = g.read().strip() g.close() From ac at codespeak.net Sun Oct 16 17:35:03 2005 From: ac at codespeak.net (ac at codespeak.net) Date: Sun, 16 Oct 2005 17:35:03 +0200 (CEST) Subject: [pypy-svn] r18692 - pypy/dist/pypy/translator Message-ID: <20051016153503.DB8A727B48@code1.codespeak.net> Author: ac Date: Sun Oct 16 17:35:03 2005 New Revision: 18692 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: (arre, samuele) Fix problem with code for classdefinitions being intermixed and clobbering the shared variable '_dic' Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Sun Oct 16 17:35:03 2005 @@ -727,6 +727,7 @@ return name def nameof_classobj(self, cls): + initcode = [] printable_name = cls.__name__ if cls.__doc__ and cls.__doc__.lstrip().startswith('NOT_RPYTHON'): #raise Exception, "%r should never be reached" % (cls,) @@ -775,13 +776,13 @@ name, self.nameof(key), self.nameof(value)) baseargs = ", ".join(basenames) - self.initcode.append('_dic = space.newdict([])') + initcode.append('_dic = space.newdict([])') for key, value in cls.__dict__.items(): if key.startswith('__'): if key in ['__module__', '__metaclass__', '__slots__','__new__']: keyname = self.nameof(key) valname = self.nameof(value) - self.initcode.append("space.setitem(_dic, %s, %s)" % ( + initcode.append("space.setitem(_dic, %s, %s)" % ( keyname, valname)) if cls.__doc__ is not None: @@ -789,16 +790,19 @@ docobj = cls.__dict__["__doc__"] if type(docobj) in (str, unicode): docstr = render_docstr(cls, "_doc = space.wrap(", ")") - self.initcode.append((docstr,)) # not splitted + initcode.append((docstr,)) # not splitted else: - self.initcode.append("_doc = %s" % self.nameof(docobj) ) - self.initcode.append("space.setitem(_dic, %s, _doc)" % (sdoc,)) + initcode.append("_doc = %s" % self.nameof(docobj) ) + initcode.append("space.setitem(_dic, %s, _doc)" % (sdoc,)) + cls_name = self.nameof(cls.__name__) + for l in initcode: + self.initcode.append(l) self.initcode.append1('_bases = space.newtuple([%(bases)s])\n' '_args = space.newtuple([%(name)s, _bases, _dic])\n' '%(klass)s = space.call(%(meta)s, _args)' % {"bases": baseargs, "klass": name, - "name" : self.nameof(cls.__name__), + "name" : cls_name, "meta" : metaclass} ) self.later(initclassobj()) From mwh at codespeak.net Sun Oct 16 17:50:15 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Sun, 16 Oct 2005 17:50:15 +0200 (CEST) Subject: [pypy-svn] r18693 - pypy/dist/pypy/translator/asm/ppcgen Message-ID: <20051016155015.57C3027B48@code1.codespeak.net> Author: mwh Date: Sun Oct 16 17:50:11 2005 New Revision: 18693 Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Log: implement srwi -- Shift Right Word Immediate Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Sun Oct 16 17:50:11 2005 @@ -508,6 +508,9 @@ def slwi(self, rA, rS, n): self.rlwinm(rA, rS, n, 0, 31-n) + def srwi(self, rA, rS, n): + self.rlwinm(rA, rS, 32-n, n, 31) + def inslwi(self, rA, rS, n, b): self.rwlimi(rA, rS, 32-b, b, b + n -1) From sanxiyn at codespeak.net Mon Oct 17 09:13:18 2005 From: sanxiyn at codespeak.net (sanxiyn at codespeak.net) Date: Mon, 17 Oct 2005 09:13:18 +0200 (CEST) Subject: [pypy-svn] r18696 - pypy/dist/pypy/translator/tool Message-ID: <20051017071318.AF6E027B68@code1.codespeak.net> Author: sanxiyn Date: Mon Oct 17 09:13:15 2005 New Revision: 18696 Modified: pypy/dist/pypy/translator/tool/cbuild.py Log: Patch from Jerub to compile on Mac OS X with Fink. Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Mon Oct 17 09:13:15 2005 @@ -255,19 +255,28 @@ return spawn_and_log def build_executable(cfilenames, outputfilename=None, include_dirs=None, - libraries=[]): + libraries=[], library_dirs=None): from distutils.ccompiler import new_compiler ext = '' extra_preargs = None - if sys.platform != 'win32': + if not include_dirs: + include_dirs = [] + if not library_dirs: + library_dirs = [] + if not sys.platform in ('win32', 'darwin'): libraries.append('m') libraries.append('pthread') extra_preargs = ['-O2', '-pthread'] # XXX 2 x hackish + if sys.platform == 'darwin': + include_dirs.append('/sw/include') if outputfilename is None: outputfilename = py.path.local(cfilenames[0]).new(ext=ext) else: outputfilename = py.path.local(outputfilename) + if sys.platform == 'darwin': + library_dirs=['/sw/lib'] + compiler = new_compiler() compiler.spawn = log_spawned_cmd(compiler.spawn) objects = [] @@ -286,7 +295,8 @@ old.chdir() compiler.link_executable(objects, str(outputfilename), libraries=libraries, - extra_preargs=extra_preargs) + extra_preargs=extra_preargs, + library_dirs=library_dirs) return str(outputfilename) def check_boehm_presence(): From arigo at codespeak.net Mon Oct 17 19:13:11 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 17 Oct 2005 19:13:11 +0200 (CEST) Subject: [pypy-svn] r18723 - in pypy/dist/pypy: annotation module/__builtin__ rpython rpython/l3interp rpython/l3interp/test rpython/ootypesystem rpython/ootypesystem/test translator/js translator/llvm translator/locality translator/locality/test translator/squeak translator/squeak/test Message-ID: <20051017171311.324B727B3E@code1.codespeak.net> Author: arigo Date: Mon Oct 17 19:13:08 2005 New Revision: 18723 Modified: pypy/dist/pypy/annotation/model.py pypy/dist/pypy/module/__builtin__/importing.py pypy/dist/pypy/rpython/l3interp/convertgraph.py (props changed) pypy/dist/pypy/rpython/l3interp/test/test_convert.py (props changed) pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/llvm/codewriter.py pypy/dist/pypy/translator/locality/ (props changed) pypy/dist/pypy/translator/locality/test/ (props changed) pypy/dist/pypy/translator/squeak/gensqueak.py pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py Log: * fixeol * untabify Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Mon Oct 17 19:13:08 2005 @@ -482,10 +482,10 @@ def lltype_to_annotation(T): s = ll_to_annotation_map.get(T) if s is None: - if isinstance(T, ootype.Instance): - return SomeOOInstance(T) + if isinstance(T, ootype.Instance): + return SomeOOInstance(T) else: - return SomePtr(T) + return SomePtr(T) else: return s Modified: pypy/dist/pypy/module/__builtin__/importing.py ============================================================================== --- pypy/dist/pypy/module/__builtin__/importing.py (original) +++ pypy/dist/pypy/module/__builtin__/importing.py Mon Oct 17 19:13:08 2005 @@ -282,7 +282,7 @@ return None else: # ImportError - msg = "No module named %s" % modulename + msg = "No module named %s" % modulename raise OperationError(space.w_ImportError, w(msg)) # __________________________________________________________________ Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Oct 17 19:13:08 2005 @@ -641,9 +641,9 @@ assert isinstance(inst, ootype._instance) assert isinstance(message, str) bm = getattr(inst, message) - m = bm.meth - m._checkargs(args) - return self.op_direct_call(m, inst, *args) + m = bm.meth + m._checkargs(args) + return self.op_direct_call(m, inst, *args) def op_ooupcast(self, INST, inst): return ootype.ooupcast(INST, inst) Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Mon Oct 17 19:13:08 2005 @@ -21,13 +21,13 @@ self._name = name self._superclass = superclass - self._methods = frozendict() + self._methods = frozendict() self._fields = frozendict() - self._add_fields(fields) - self._add_methods(methods) + self._add_fields(fields) + self._add_methods(methods) - self._null = _null_instance(self) + self._null = _null_instance(self) self._class = _class(self) def _defl(self): @@ -46,7 +46,7 @@ for name, defn in fields.iteritems(): if self._lookup(name) is not None: raise TypeError("Cannot add field %r: method already exists" % name) - + if self._superclass is not None: if self._superclass._has_field(name): raise TypeError("Field %r exists in superclass" % name) @@ -65,7 +65,7 @@ if ootype != typeOf(default): raise TypeError("Expected type %r for default" % ootype) - self._fields.update(fields) + self._fields.update(fields) def _add_methods(self, methods): # Note to the unwary: _add_methods adds *methods* whereas @@ -73,8 +73,8 @@ # if you are in the right state of mind (swiss?), but # certainly not necessarily if not. for name, method in methods.iteritems(): - if self._has_field(name): - raise TypeError("Can't add method %r: field already exists" % name) + if self._has_field(name): + raise TypeError("Can't add method %r: field already exists" % name) if not isinstance(typeOf(method), Meth): raise TypeError("added methods must be _meths, not %s" % type(defn)) self._methods.update(methods) @@ -91,7 +91,7 @@ self._fields[name] return True except KeyError: - if self._superclass is None: + if self._superclass is None: return False return self._superclass._has_field(name) @@ -100,7 +100,7 @@ try: return self._fields[name][0] except KeyError: - if self._superclass is None: + if self._superclass is None: raise TypeError("No field names %r" % name) return self._superclass._field_type(name) @@ -116,18 +116,18 @@ return meth def _allfields(self): - if self._superclass is None: - all = {} - else: - all = self._superclass._allfields() - all.update(self._fields) - return all + if self._superclass is None: + all = {} + else: + all = self._superclass._allfields() + all.update(self._fields) + return all class StaticMethod(OOType): def __init__(self, args, result): - self.ARGS = tuple(args) - self.RESULT = result + self.ARGS = tuple(args) + self.RESULT = result def _example(self): _retval = self.RESULT._example() @@ -195,7 +195,7 @@ def _checkargs(self, args): if len(args) != len(self._TYPE.ARGS): - raise TypeError,"calling %r with wrong argument number: %r" % (self._TYPE, args) + raise TypeError,"calling %r with wrong argument number: %r" % (self._TYPE, args) for a, ARG in zip(args, self._TYPE.ARGS): if not isCompatibleType(typeOf(a), ARG): Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Mon Oct 17 19:13:08 2005 @@ -24,21 +24,21 @@ def __init__(self, rtyper, classdef, does_need_gc=True): AbstractInstanceRepr.__init__(self, rtyper, classdef) - self.baserepr = None + self.baserepr = None b = self.classdef.basedef if b is not None: - self.baserepr = getinstancerepr(rtyper, b) + self.baserepr = getinstancerepr(rtyper, b) b = self.baserepr.lowleveltype self.lowleveltype = ootype.Instance(classdef.cls.__name__, b, {}, {}) self.prebuiltinstances = {} # { id(x): (x, _ptr) } - self.object_type = self.lowleveltype + self.object_type = self.lowleveltype def _setup_repr(self): - if self.baserepr is not None: - self.allfields = self.baserepr.allfields.copy() - else: - self.allfields = {} + if self.baserepr is not None: + self.allfields = self.baserepr.allfields.copy() + else: + self.allfields = {} self.allmethods = {} fields = {} @@ -46,8 +46,8 @@ for name, attrdef in attrs: if not attrdef.readonly: - repr = self.rtyper.getrepr(attrdef.s_value) - self.allfields[name] = repr + repr = self.rtyper.getrepr(attrdef.s_value) + self.allfields[name] = repr oot = repr.lowleveltype fields[name] = oot @@ -56,20 +56,20 @@ methods = {} baseInstance = self.lowleveltype._superclass - for classdef in self.classdef.getmro(): - attrs = classdef.attrs.items() - for name, attrdef in attrs: - if attrdef.readonly: - try: - impl = self.classdef.cls.__dict__[name] - except KeyError: - pass - else: - f, inputs, ret = getsignature(self.rtyper, impl) - M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) - m = ootype.meth(M, _name=name, _callable=impl) - methods[name] = m - + for classdef in self.classdef.getmro(): + attrs = classdef.attrs.items() + for name, attrdef in attrs: + if attrdef.readonly: + try: + impl = self.classdef.cls.__dict__[name] + except KeyError: + pass + else: + f, inputs, ret = getsignature(self.rtyper, impl) + M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) + m = ootype.meth(M, _name=name, _callable=impl) + methods[name] = m + ootype.addMethods(self.lowleveltype, methods) def rtype_getattr(self, hop): @@ -127,21 +127,21 @@ [inputconst(ootype.Void, self.lowleveltype)], self.lowleveltype) def initialize_prebuilt_instance(self, value, result): - # then add instance attributes from this level - for name, (oot, default) in self.lowleveltype._allfields().items(): - if oot is ootype.Void: - llattrvalue = None - elif name == '_hash_cache_': # hash() support - llattrvalue = hash(value) - else: - try: - attrvalue = getattr(value, name) - except AttributeError: - warning("prebuilt instance %r has no attribute %r" % ( - value, name)) - continue - llattrvalue = self.allfields[name].convert_const(attrvalue) - setattr(result, name, llattrvalue) + # then add instance attributes from this level + for name, (oot, default) in self.lowleveltype._allfields().items(): + if oot is ootype.Void: + llattrvalue = None + elif name == '_hash_cache_': # hash() support + llattrvalue = hash(value) + else: + try: + attrvalue = getattr(value, name) + except AttributeError: + warning("prebuilt instance %r has no attribute %r" % ( + value, name)) + continue + llattrvalue = self.allfields[name].convert_const(attrvalue) + setattr(result, name, llattrvalue) class __extend__(pairtype(InstanceRepr, InstanceRepr)): Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Mon Oct 17 19:13:08 2005 @@ -20,12 +20,12 @@ def check_ootype(v): t = v.concretetype assert isinstance(t, ootype.Primitive) or isinstance(t, ootype.OOType) - + for block in graph.iterblocks(): - for var in block.getvariables(): - check_ootype(var) - for const in block.getconstants(): - check_ootype(const) + for var in block.getvariables(): + check_ootype(var) + for const in block.getconstants(): + check_ootype(const) def test_simple(): def f(a, b): @@ -108,10 +108,10 @@ def test_override(): def dummyfn(flag): - if flag: - inst = HasAMethod() - else: - inst = OverridesAMethod() + if flag: + inst = HasAMethod() + else: + inst = OverridesAMethod() return inst.f() result = interpret(dummyfn, [True], type_system='ootype') assert result == 1 Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Mon Oct 17 19:13:08 2005 @@ -169,8 +169,8 @@ self.append('%s = %s(%s)' % (targetvar, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): - if fromtype == 'void' and targettype == 'void': - return + if fromtype == 'void' and targettype == 'void': + return if targettype == fromtype: self.append("%(targetvar)s = %(fromvar)s" % locals()) elif targettype in ('int','uint',): Modified: pypy/dist/pypy/translator/llvm/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm/codewriter.py Mon Oct 17 19:13:08 2005 @@ -112,8 +112,8 @@ tail_ = '' else: tail_ = tail - if tail_: - tail_ += ' ' + if tail_: + tail_ += ' ' args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) if except_label: self.genllvm.exceptionpolicy.invoke(self, targetvar, tail_, cconv, returntype, functionref, args, label, except_label) @@ -124,8 +124,8 @@ self.indent("%s = %scall %s %s %s(%s)" % (targetvar, tail_, cconv, returntype, functionref, args)) def cast(self, targetvar, fromtype, fromvar, targettype): - if fromtype == 'void' and targettype == 'void': - return + if fromtype == 'void' and targettype == 'void': + return self.indent("%(targetvar)s = cast %(fromtype)s " "%(fromvar)s to %(targettype)s" % locals()) Modified: pypy/dist/pypy/translator/squeak/gensqueak.py ============================================================================== --- pypy/dist/pypy/translator/squeak/gensqueak.py (original) +++ pypy/dist/pypy/translator/squeak/gensqueak.py Mon Oct 17 19:13:08 2005 @@ -19,7 +19,7 @@ def camel_case(str): words = str.split('_') for i in range(1, len(words)): - words[i] = words[i].capitalize() + words[i] = words[i].capitalize() return ''.join(words) def arg_names(func, names = None): @@ -27,54 +27,54 @@ # http://docs.python.org/ref/types.html#l2h-139 co = func.func_code if not names: - names = co.co_varnames + names = co.co_varnames return names[:co.co_argcount] def selector(name, args): s = name if args: - s += '_' - for arg in args: - s += arg + ':' + s += '_' + for arg in args: + s += arg + ':' return camel_case(s) def signature(sel, args): if (':' in sel): - parts = [] - names = sel.split(':') -# assert len(names) == len(args) - while args: - parts.append(names.pop(0) + ': ' + args.pop(0)) - return ' '.join(parts) + parts = [] + names = sel.split(':') +# assert len(names) == len(args) + while args: + parts.append(names.pop(0) + ': ' + args.pop(0)) + return ' '.join(parts) elif not sel[0].isalnum(): -# assert len(args) == 1 +# assert len(args) == 1 return "%s %s" %(sel, args[0]) else: -# assert len(args) == 0 - return sel +# assert len(args) == 0 + return sel class LoopFinder: def __init__(self, startblock): - self.loops = {} - self.parents = {startblock: startblock} - self.temps = {} - self.seen = [] - self.visit_Block(startblock) + self.loops = {} + self.parents = {startblock: startblock} + self.temps = {} + self.seen = [] + self.visit_Block(startblock) def visit_Block(self, block, switches=[]): - #self.temps.has_key() - self.seen.append(block) - if block.exitswitch: - switches.append(block) - self.parents[block] = block - for link in block.exits: - self.visit_Link(link, switches) + #self.temps.has_key() + self.seen.append(block) + if block.exitswitch: + switches.append(block) + self.parents[block] = block + for link in block.exits: + self.visit_Link(link, switches) def visit_Link(self, link, switches): - if link.target in switches: - self.loops[link.target] = True - if not link.target in self.seen: - self.parents[link.target] = self.parents[link.prevblock] - self.visit_Block(link.target, switches) + if link.target in switches: + self.loops[link.target] = True + if not link.target in self.seen: + self.parents[link.target] = self.parents[link.prevblock] + self.visit_Block(link.target, switches) class GenSqueak: @@ -84,66 +84,66 @@ self.modname = (modname or translator.functions[0].__name__) self.sqnames = { - Constant(None).key: 'nil', - Constant(False).key: 'false', - Constant(True).key: 'true', - } + Constant(None).key: 'nil', + Constant(False).key: 'false', + Constant(True).key: 'true', + } self.seennames = {} self.pendingfunctions = [] self.pendingclasses = [] self.pendingmethods = [] - self.classes = [] - self.methods = [] + self.classes = [] + self.methods = [] - t = self.translator - func = t.functions[0] - graph = t.getflowgraph(func) - simplify_graph(graph) + t = self.translator + func = t.functions[0] + graph = t.getflowgraph(func) + simplify_graph(graph) remove_direct_loops(t, graph) checkgraph(graph) - #self.translator.view() + #self.translator.view() self.nameof(func) #add to pending file = self.sqdir.join('%s.st' % func.__name__).open('w') self.gen_source(file) - file.close() - #self.translator.view() + file.close() + #self.translator.view() def gen_source(self, file): - while self.pendingfunctions or self.pendingclasses or self.pendingmethods: - while self.pendingfunctions: - func = self.pendingfunctions.pop() - self.gen_sqfunction(func, file) - while self.pendingclasses: - inst = self.pendingclasses.pop() - self.gen_sqclass(inst, file) - while self.pendingmethods: - (inst, meth) = self.pendingmethods.pop() - self.gen_sqmethod(inst, meth, file) + while self.pendingfunctions or self.pendingclasses or self.pendingmethods: + while self.pendingfunctions: + func = self.pendingfunctions.pop() + self.gen_sqfunction(func, file) + while self.pendingclasses: + inst = self.pendingclasses.pop() + self.gen_sqclass(inst, file) + while self.pendingmethods: + (inst, meth) = self.pendingmethods.pop() + self.gen_sqmethod(inst, meth, file) def gen_sqclass(self, inst, f): - self.classes.append(inst) - print >> f, """%s subclass: #%s - instanceVariableNames: '%s' - classVariableNames: '' - poolDictionaries: '' - category: 'PyPy-Test'! - """ % ( - self.nameof_Instance(inst._superclass), - self.nameof_Instance(inst), - ' '.join(inst._fields.iterkeys())) + self.classes.append(inst) + print >> f, """%s subclass: #%s + instanceVariableNames: '%s' + classVariableNames: '' + poolDictionaries: '' + category: 'PyPy-Test'! + """ % ( + self.nameof_Instance(inst._superclass), + self.nameof_Instance(inst), + ' '.join(inst._fields.iterkeys())) def gen_sqmethod(self, inst, meth, f): - if (inst, meth) in self.methods: - return - self.methods.append((inst, meth)) - print >> f, "!%s methodsFor: 'methods' stamp: 'pypy 1/1/2000 00:00'!" % ( + if (inst, meth) in self.methods: + return + self.methods.append((inst, meth)) + print >> f, "!%s methodsFor: 'methods' stamp: 'pypy 1/1/2000 00:00'!" % ( self.nameof_Instance(inst)) - print >> f, "%s" % meth - print >> f, ' "XXX methods not generated yet"' - print >> f, "! !" - print >> f + print >> f, "%s" % meth + print >> f, ' "XXX methods not generated yet"' + print >> f, "! !" + print >> f def gen_sqfunction(self, func, f): @@ -156,128 +156,128 @@ else: raise TypeError, "expr(%r)" % (v,) - def oper(op): - args = [expr(arg) for arg in op.args] - if op.opname == "oosend": - name = op.args[0].value - receiver = args[1] - args = args[2:] - self.note_meth(op.args[1].concretetype, name) - elif op.opname == "oogetfield": - receiver = args[0] - name = op.args[1].value - args = args[2:] - elif op.opname == "oosetfield": - receiver = args[0] - name = op.args[1].value - args = args[2:] - else: - name = op.opname - receiver = args[0] - args = args[1:] - argnames = ['with'] * len(args) - if argnames: - argnames[0] = '' - sel = selector(name, argnames) - if op.opname != "oosend": - sel = selectormap.get(sel, sel) - return "%s := %s %s." % (expr(op.result), receiver, signature(sel, args)) - - def render_return(args): - if len(args) == 2: - # exception - exc_cls = expr(args[0]) - exc_val = expr(args[1]) - yield "(PyOperationError class: %s value: %s) signal." % (exc_cls, exc_val) - else: - # regular return block - retval = expr(args[0]) - yield "^%s" % retval - - def render_link(link): - block = link.target - if link.args: - for i in range(len(link.args)): - yield '%s := %s.' % (expr(block.inputargs[i]), expr(link.args[i])) - for line in render_block(block): - yield line - - def render_block(block): - if loops.has_key(block): - if not loops[block]: - yield '"skip1"' - return - yield "[" - for op in block.operations: - yield "%s" % oper(op) - if len(block.exits) == 0: + def oper(op): + args = [expr(arg) for arg in op.args] + if op.opname == "oosend": + name = op.args[0].value + receiver = args[1] + args = args[2:] + self.note_meth(op.args[1].concretetype, name) + elif op.opname == "oogetfield": + receiver = args[0] + name = op.args[1].value + args = args[2:] + elif op.opname == "oosetfield": + receiver = args[0] + name = op.args[1].value + args = args[2:] + else: + name = op.opname + receiver = args[0] + args = args[1:] + argnames = ['with'] * len(args) + if argnames: + argnames[0] = '' + sel = selector(name, argnames) + if op.opname != "oosend": + sel = selectormap.get(sel, sel) + return "%s := %s %s." % (expr(op.result), receiver, signature(sel, args)) + + def render_return(args): + if len(args) == 2: + # exception + exc_cls = expr(args[0]) + exc_val = expr(args[1]) + yield "(PyOperationError class: %s value: %s) signal." % (exc_cls, exc_val) + else: + # regular return block + retval = expr(args[0]) + yield "^%s" % retval + + def render_link(link): + block = link.target + if link.args: + for i in range(len(link.args)): + yield '%s := %s.' % (expr(block.inputargs[i]), expr(link.args[i])) + for line in render_block(block): + yield line + + def render_block(block): + if loops.has_key(block): + if not loops[block]: + yield '"skip1"' + return + yield "[" + for op in block.operations: + yield "%s" % oper(op) + if len(block.exits) == 0: for line in render_return(block.inputargs): - yield line + yield line return - elif block.exitswitch is None: + elif block.exitswitch is None: # single-exit block assert len(block.exits) == 1 - for line in render_link(block.exits[0]): - yield line - else: + for line in render_link(block.exits[0]): + yield line + else: #exitswitch - if loops.has_key(block): - if loops[block]: - loops[block] = False - yield "%s] whileTrue: [" % expr(block.exitswitch) - for line in render_link(block.exits[True]): - yield " %s" % line - yield "]." - for line in render_link(block.exits[False]): - yield "%s" % line - else: - yield "%s ifTrue: [" % expr(block.exitswitch) - for line in render_link(block.exits[True]): - yield " %s" % line - yield "] ifFalse: [" - for line in render_link(block.exits[False]): - yield " %s" % line - yield "]" + if loops.has_key(block): + if loops[block]: + loops[block] = False + yield "%s] whileTrue: [" % expr(block.exitswitch) + for line in render_link(block.exits[True]): + yield " %s" % line + yield "]." + for line in render_link(block.exits[False]): + yield "%s" % line + else: + yield "%s ifTrue: [" % expr(block.exitswitch) + for line in render_link(block.exits[True]): + yield " %s" % line + yield "] ifFalse: [" + for line in render_link(block.exits[False]): + yield " %s" % line + yield "]" t = self.translator graph = t.getflowgraph(func) start = graph.startblock - args = [expr(arg) for arg in start.inputargs] - print >> f, '%s' % signature(self.nameof(func), args) + args = [expr(arg) for arg in start.inputargs] + print >> f, '%s' % signature(self.nameof(func), args) - loops = LoopFinder(start).loops + loops = LoopFinder(start).loops - for line in render_block(start): - print >> f, ' %s' % line - print >> f + for line in render_block(start): + print >> f, ' %s' % line + print >> f def nameof(self, obj): key = Constant(obj).key try: return self.sqnames[key] except KeyError: - for cls in type(obj).__mro__: - meth = getattr(self, - 'nameof_' + cls.__name__.replace(' ', ''), - None) - if meth: - break - else: - types = ['nameof_'+t.__name__ for t in type(obj).__mro__] - raise Exception, "nameof(%r): no method %s" % (obj, types) - name = meth(obj) + for cls in type(obj).__mro__: + meth = getattr(self, + 'nameof_' + cls.__name__.replace(' ', ''), + None) + if meth: + break + else: + types = ['nameof_'+t.__name__ for t in type(obj).__mro__] + raise Exception, "nameof(%r): no method %s" % (obj, types) + name = meth(obj) self.sqnames[key] = name return name def nameof_int(self, i): - return str(i) + return str(i) def nameof_str(self, s): - return "'s'" + return "'s'" def nameof_function(self, func): - #XXX this should actually be a StaticMeth + #XXX this should actually be a StaticMeth printable_name = '(%s:%d) %s' % ( func.func_globals.get('__name__', '?'), func.func_code.co_firstlineno, @@ -292,28 +292,28 @@ print "skipped", printable_name return self.skipped_function(func) name = self.unique_name(func.__name__) - args = arg_names(func) - sel = selector(name, args) + args = arg_names(func) + sel = selector(name, args) self.pendingfunctions.append(func) return sel def nameof_Instance(self, inst): - if inst is None: - #empty superclass - return "Object" - self.note_Instance(inst) - return "Py%s" % inst._name.capitalize() + if inst is None: + #empty superclass + return "Object" + self.note_Instance(inst) + return "Py%s" % inst._name.capitalize() def note_Instance(self, inst): - if inst not in self.classes: - if inst not in self.pendingclasses: - self.pendingclasses.append(inst) + if inst not in self.classes: + if inst not in self.pendingclasses: + self.pendingclasses.append(inst) def note_meth(self, inst, meth): bm = (inst, meth) - if bm not in self.methods: - if bm not in self.pendingmethods: - self.pendingmethods.append(bm) + if bm not in self.methods: + if bm not in self.pendingmethods: + self.pendingmethods.append(bm) def unique_name(self, basename): n = self.seennames.get(basename, 0) Modified: pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py ============================================================================== --- pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py (original) +++ pypy/dist/pypy/translator/squeak/test/test_squeaktrans.py Mon Oct 17 19:13:08 2005 @@ -6,9 +6,9 @@ def looping(i = (int), j = (int)): while i > 0: - i -= 1 - while j > 0: - j -= 1 + i -= 1 + while j > 0: + j -= 1 class TestSqueakTrans: From arigo at codespeak.net Mon Oct 17 20:07:38 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 17 Oct 2005 20:07:38 +0200 (CEST) Subject: [pypy-svn] r18724 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem ootypesystem/test Message-ID: <20051017180738.8120E27B3F@code1.codespeak.net> Author: arigo Date: Mon Oct 17 20:07:36 2005 New Revision: 18724 Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/rclass.py pypy/dist/pypy/rpython/rtyper.py Log: Support for general class attributes in the ootyper: * moved the method/not-a-method distinction logic from lltypesystem/ up to rpython/. * three dicts: self.allfields, self.allmethods, self.allclassattributes. * generally attach a graph to the methods in addition to a _callable. * build an accessor method for each non-constant class attribute (it's a method that just returns the value that corresponds to the class where the call arrived). * annotating low-level helpers in ootypesystem seems to work out of the box in simple cases (after a minor fix in rtyper.py). Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Mon Oct 17 20:07:36 2005 @@ -98,7 +98,10 @@ for name, attrdef in attrs: if attrdef.readonly: s_value = attrdef.s_value - s_value = self.prepare_method(name, s_value, allmethods) + s_unboundmethod = self.prepare_method(s_value) + if s_unboundmethod is not None: + allmethods[name] = True + s_value = s_unboundmethod r = self.rtyper.getrepr(s_value) mangled_name = 'cls_' + name clsfields[name] = mangled_name, r @@ -125,36 +128,6 @@ self.allmethods = allmethods self.vtable = None - def prepare_method(self, name, s_value, allmethods): - # special-casing for methods: - # - a class (read-only) attribute that would contain a PBC - # with {func: classdef...} is probably meant to be used as a - # method, but in corner cases it could be a constant object - # of type MethodType that just sits here in the class. But - # as MethodType has a custom __get__ too and we don't support - # it, it's a very bad idea anyway. - if isinstance(s_value, annmodel.SomePBC): - s_value = self.classdef.matching(s_value) - debound = {} - count = 0 - for x, classdef in s_value.prebuiltinstances.items(): - if isclassdef(classdef): - #if classdef.commonbase(self.classdef) != self.classdef: - # raise TyperError("methods from PBC set %r don't belong " - # "in %r" % (s_value.prebuiltinstances, - # self.classdef.cls)) - count += 1 - classdef = True - debound[x] = classdef - if count > 0: - if count != len(s_value.prebuiltinstances): - raise TyperError("mixing functions and methods " - "in PBC set %r" % ( - s_value.prebuiltinstances,)) - s_value = annmodel.SomePBC(debound) - allmethods[name] = True - return s_value - def convert_const(self, value): if not isinstance(value, (type, types.ClassType)): raise TyperError("not a class: %r" % (value,)) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Mon Oct 17 20:07:36 2005 @@ -1,9 +1,10 @@ from pypy.rpython.rmodel import inputconst from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \ - getinstancerepr + getinstancerepr, getclassrepr from pypy.rpython.rpbc import getsignature from pypy.rpython.ootypesystem import ootype from pypy.annotation.pairtype import pairtype +from pypy.tool.sourcetools import func_with_new_name CLASSTYPE = ootype.Class @@ -36,10 +37,13 @@ def _setup_repr(self): if self.baserepr is not None: - self.allfields = self.baserepr.allfields.copy() + allfields = self.baserepr.allfields.copy() + allmethods = self.baserepr.allmethods.copy() + allclassattributes = self.baserepr.allclassattributes.copy() else: - self.allfields = {} - self.allmethods = {} + allfields = {} + allmethods = {} + allclassattributes = {} fields = {} attrs = self.classdef.attrs.items() @@ -47,44 +51,89 @@ for name, attrdef in attrs: if not attrdef.readonly: repr = self.rtyper.getrepr(attrdef.s_value) - self.allfields[name] = repr + allfields[name] = repr oot = repr.lowleveltype fields[name] = oot ootype.addFields(self.lowleveltype, fields) methods = {} + classattributes = {} baseInstance = self.lowleveltype._superclass + classrepr = getclassrepr(self.rtyper, self.classdef) for classdef in self.classdef.getmro(): attrs = classdef.attrs.items() for name, attrdef in attrs: - if attrdef.readonly: - try: - impl = self.classdef.cls.__dict__[name] - except KeyError: - pass - else: - f, inputs, ret = getsignature(self.rtyper, impl) - M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) - m = ootype.meth(M, _name=name, _callable=impl) - methods[name] = m + if not attrdef.readonly: + continue + try: + impl = self.classdef.cls.__dict__[name] + except KeyError: + continue + if classrepr.prepare_method(attrdef.s_value) is not None: + # a regular method + f, inputs, ret = getsignature(self.rtyper, impl) + M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) + m = ootype.meth(M, _name=name, _callable=impl, + graph=f.graph) + methods[name] = m + allmethods[name] = True + else: + # a non-method class attribute + allclassattributes[name] = True + if not attrdef.s_value.is_constant(): + classattributes[name] = attrdef.s_value, impl ootype.addMethods(self.lowleveltype, methods) - + self.allfields = allfields + self.allmethods = allmethods + self.allclassattributes = allclassattributes + + # step 2: provide accessor methods for class attributes that are + # really overridden in subclasses (this is done after the rest of + # the initialization because convert_const can require 'self' to + # be fully initialized) + for name, (s_value, impl) in classattributes.items(): + r = self.rtyper.getrepr(s_value) + oovalue = r.convert_const(impl) + m = self.attach_class_attr_accessor(name, oovalue, r.lowleveltype) + + def attach_class_attr_accessor(self, name, oovalue, oovaluetype): + def ll_getclassattr(self): + return oovalue + ll_getclassattr = func_with_new_name(ll_getclassattr, 'll_get_' + name) + sm = self.rtyper.annotate_helper(ll_getclassattr, [self.lowleveltype]) + M = ootype.Meth([], oovaluetype) + m = ootype.meth(M, _name=name, _callable=ll_getclassattr, + graph=sm.graph) + ootype.addMethods(self.lowleveltype, {name: m}) + def rtype_getattr(self, hop): vlist = hop.inputargs(self, ootype.Void) attr = hop.args_s[1].const s_inst = hop.args_s[0] - meth = self.lowleveltype._lookup(attr) - if meth is not None: + if attr in self.allfields: + # regular instance attributes + self.lowleveltype._check_field(attr) + return hop.genop("oogetfield", vlist, + resulttype = hop.r_result.lowleveltype) + elif attr in self.allmethods: # special case for methods: represented as their 'self' only # (see MethodsPBCRepr) return hop.r_result.get_method_from_instance(self, vlist[0], hop.llops) - self.lowleveltype._check_field(attr) - return hop.genop("oogetfield", vlist, - resulttype = hop.r_result.lowleveltype) + elif attr in self.allclassattributes: + # class attributes + if hop.s_result.is_constant(): + oovalue = hop.r_result.convert_const(hop.s_result.const) + return hop.inputconst(hop.r_result, oovalue) + else: + cname = hop.inputconst(ootype.Void, attr) + return hop.genop("oosend", [cname, vlist[0]], + resulttype = hop.r_result.lowleveltype) + else: + raise TyperError("no attribute %r on %r" % (attr, self)) def rtype_setattr(self, hop): attr = hop.args_s[1].const Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Mon Oct 17 20:07:36 2005 @@ -129,3 +129,30 @@ return inst.f() result = interpret(dummyfn, [], type_system='ootype') assert result == 3 + +class HasClassAttr(object): + a = 3 + def f(self, n): + return n + self.a + +class OverridesClassAttr(HasClassAttr): + a = 42 + +def test_single_class_attr(): + def dummyfn(): + inst = HasClassAttr() + return inst.f(100) + result = interpret(dummyfn, [], type_system='ootype') + assert result == 103 + +def test_class_attr(): + def dummyfn(flag): + if flag: + inst = HasClassAttr() + else: + inst = OverridesClassAttr() + return inst.f(100) + result = interpret(dummyfn, [True], type_system='ootype') + assert result == 103 + result = interpret(dummyfn, [False], type_system='ootype') + assert result == 142 Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Mon Oct 17 20:07:36 2005 @@ -80,6 +80,35 @@ # return getclassrepr(self.rtyper, subclassdef).getruntime() + def prepare_method(self, s_value): + # special-casing for methods: + # - a class (read-only) attribute that would contain a PBC + # with {func: classdef...} is probably meant to be used as a + # method, but in corner cases it could be a constant object + # of type MethodType that just sits here in the class. But + # as MethodType has a custom __get__ too and we don't support + # it, it's a very bad idea anyway. + if isinstance(s_value, annmodel.SomePBC): + s_value = self.classdef.matching(s_value) + debound = {} + count = 0 + for x, classdef in s_value.prebuiltinstances.items(): + if isclassdef(classdef): + #if classdef.commonbase(self.classdef) != self.classdef: + # raise TyperError("methods from PBC set %r don't belong " + # "in %r" % (s_value.prebuiltinstances, + # self.classdef.cls)) + count += 1 + classdef = True + debound[x] = classdef + if count > 0: + if count != len(s_value.prebuiltinstances): + raise TyperError("mixing functions and methods " + "in PBC set %r" % ( + s_value.prebuiltinstances,)) + return annmodel.SomePBC(debound) + return None # not a method + def get_ll_eq_function(self): return None Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Mon Oct 17 20:07:36 2005 @@ -53,7 +53,7 @@ def getconcretetype(v): return self.bindingrepr(v).lowleveltype - return LowLevelTypeSystem.instance.getcallable( + return self.type_system.getcallable( self.annotator.translator, graphfunc, getconcretetype) self.getfunctionptr = getfunctionptr From arigo at codespeak.net Mon Oct 17 20:08:50 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 17 Oct 2005 20:08:50 +0200 (CEST) Subject: [pypy-svn] r18725 - pypy/dist/pypy/rpython Message-ID: <20051017180850.CDAD827B41@code1.codespeak.net> Author: arigo Date: Mon Oct 17 20:08:50 2005 New Revision: 18725 Modified: pypy/dist/pypy/rpython/llinterp.py Log: Use deref() instead of reading _obj. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Mon Oct 17 20:08:50 2005 @@ -242,8 +242,9 @@ raise LLException(etype, evalue) def invoke_callable_with_pyexceptions(self, fptr, *args): + obj = self.llinterpreter.typer.type_system.deref(fptr) try: - return fptr._obj._callable(*args) + return obj._callable(*args) except Exception, e: #print "GOT A CPYTHON EXCEPTION:", e.__class__, e self.make_llexception(e) From boria at codespeak.net Mon Oct 17 23:01:14 2005 From: boria at codespeak.net (boria at codespeak.net) Date: Mon, 17 Oct 2005 23:01:14 +0200 (CEST) Subject: [pypy-svn] r18726 - pypy/dist/pypy/rpython Message-ID: <20051017210114.051B827B3F@code1.codespeak.net> Author: boria Date: Mon Oct 17 23:01:13 2005 New Revision: 18726 Modified: pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/typesystem.py Log: * Small cleanup. No need to treat BUILTIN_TYPER as a special case here. Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Mon Oct 17 23:01:13 2005 @@ -57,7 +57,8 @@ except KeyError: try: rtyper = hop.rtyper - bltintyper = rtyper.type_system.BUILTIN_TYPER[self.builtinfunc] + bltintyper = rtyper.type_system.rbuiltin.\ + BUILTIN_TYPER[self.builtinfunc] except KeyError: raise TyperError("don't know about built-in function %r" % ( self.builtinfunc,)) Modified: pypy/dist/pypy/rpython/typesystem.py ============================================================================== --- pypy/dist/pypy/rpython/typesystem.py (original) +++ pypy/dist/pypy/rpython/typesystem.py Mon Oct 17 23:01:13 2005 @@ -17,16 +17,11 @@ None, None, ['__doc__']) except ImportError: return None - if name in ('rclass', 'rpbc'): + if name in ('rclass', 'rpbc', 'rbuiltin'): mod = load(name) if mod is not None: setattr(self, name, mod) return mod - elif name == "BUILTIN_TYPER": - rbuiltin = load('rbuiltin') - if rbuiltin is not None: - self.BUILTIN_TYPER = rbuiltin.BUILTIN_TYPER - return self.BUILTIN_TYPER raise AttributeError(name) From ericvrp at codespeak.net Tue Oct 18 10:04:52 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 18 Oct 2005 10:04:52 +0200 (CEST) Subject: [pypy-svn] r18727 - pypy/dist/pypy/translator/js Message-ID: <20051018080452.1EA4427B42@code1.codespeak.net> Author: ericvrp Date: Tue Oct 18 10:04:51 2005 New Revision: 18727 Added: pypy/dist/pypy/translator/js/exception.txt - copied, changed from r18664, pypy/dist/pypy/translator/js/exception.py pypy/dist/pypy/translator/js/gc.txt - copied, changed from r18676, pypy/dist/pypy/translator/js/gc.py Removed: pypy/dist/pypy/translator/js/exception.py pypy/dist/pypy/translator/js/gc.py Log: * Keep exception handling and garbage collection policies for documentation. For exception handling IMHO it makes sence to use Javascript's own only. Dito for garbage collection. From arigo at codespeak.net Tue Oct 18 10:42:10 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 10:42:10 +0200 (CEST) Subject: [pypy-svn] r18728 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051018084210.1DD3D27B42@code1.codespeak.net> Author: arigo Date: Tue Oct 18 10:42:09 2005 New Revision: 18728 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: ootyper: class attributes as default values for instance attributes. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Oct 18 10:42:09 2005 @@ -43,6 +43,7 @@ return '%s(%s)' % (self.__class__.__name__, self._name) def _add_fields(self, fields): + fields = fields.copy() # mutated below for name, defn in fields.iteritems(): if self._lookup(name) is not None: raise TypeError("Cannot add field %r: method already exists" % name) @@ -63,7 +64,7 @@ raise TypeError("Attempting to store method in field") if ootype != typeOf(default): - raise TypeError("Expected type %r for default" % ootype) + raise TypeError("Expected type %r for default" % (ootype,)) self._fields.update(fields) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue Oct 18 10:42:09 2005 @@ -90,10 +90,22 @@ self.allmethods = allmethods self.allclassattributes = allclassattributes - # step 2: provide accessor methods for class attributes that are - # really overridden in subclasses (this is done after the rest of - # the initialization because convert_const can require 'self' to - # be fully initialized) + # the following is done after the rest of the initialization because + # convert_const can require 'self' to be fully initialized. + + # step 2: provide default values for fields + for name, oot in fields.items(): + try: + impl = getattr(self.classdef.cls, name) + except AttributeError: + pass + else: + r = allfields[name] + oovalue = r.convert_const(impl) + ootype.addFields(self.lowleveltype, {name: (oot, oovalue)}) + + # step 3: provide accessor methods for class attributes that are + # really overridden in subclasses for name, (s_value, impl) in classattributes.items(): r = self.rtyper.getrepr(s_value) oovalue = r.convert_const(impl) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Tue Oct 18 10:42:09 2005 @@ -130,6 +130,18 @@ result = interpret(dummyfn, [], type_system='ootype') assert result == 3 +def test_recursive_prebuilt_instance(): + a = EmptyBase() + b = EmptyBase() + a.x = 5 + b.x = 6 + a.peer = b + b.peer = a + def dummyfn(): + return a.peer.peer.peer.x + res = interpret(dummyfn, [], type_system='ootype') + assert res == 6 + class HasClassAttr(object): a = 3 def f(self, n): @@ -156,3 +168,13 @@ assert result == 103 result = interpret(dummyfn, [False], type_system='ootype') assert result == 142 + +def test_classattr_as_defaults(): + class MySubclass(HasClassAttr): + pass + def dummyfn(): + x = MySubclass() + x.a += 1 + return x.a + res = interpret(dummyfn, [], type_system='ootype') + assert res == 4 From ericvrp at codespeak.net Tue Oct 18 11:04:12 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 18 Oct 2005 11:04:12 +0200 (CEST) Subject: [pypy-svn] r18729 - pypy/dist/pypy/translator/js Message-ID: <20051018090412.887A727B42@code1.codespeak.net> Author: ericvrp Date: Tue Oct 18 11:04:11 2005 New Revision: 18729 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/extfuncnode.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/node.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py Log: Working on exception handling. Some cleaning up. Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Tue Oct 18 11:04:11 2005 @@ -40,30 +40,9 @@ else: codewriter.declare(self.ref + ' = new Array()') - def get_length(self): - """ returns logical length of array """ - items = self.value.items - return len(items) - - def get_arrayvalue(self): - items = self.value.items - l = len(items) - r = "[%s]" % ", ".join([self.db.repr_constant(v)[1] for v in items]) - return l, r - def get_ref(self): return self.ref - #def get_pbcref(self, toptr): - # return self.ref - # #ref = self.ref - # #p, c = lltype.parentlink(self.value) - # #assert p is None, "child arrays are NOT needed by rtyper" - # # - # #fromptr = "%s*" % self.get_typerepr() - # #ref = "cast(%s %s to %s)" % (fromptr, ref, toptr) - # #return ref - def get_childref(self, index): return "getelementptr(%s* %s, int 0, uint 1, int %s)" %( self.get_typerepr(), @@ -71,8 +50,12 @@ index) def constantvalue(self): - physicallen, arrayrepr = self.get_arrayvalue() - return arrayrepr + lines = [] + for i, v in enumerate(self.value.items): + s = self.db.repr_constant(v)[1] + line = "%s[%d] = %s" % (self.ref, i, s) + lines.append(line) + return lines class StrArrayNode(ArrayNode): @@ -83,21 +66,18 @@ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "!#$%&()*+,-./:;<=>?@[]^_`{|}~ '")]) - def get_arrayvalue(self): - items = self.value.items - item_length = len(items) - s = [] - for c in items: + def constantvalue(self): + s = '"' + for c in self.value.items: if ord(c) in StrArrayNode.printables: - s.append(c) + s += c else: - s.append("\\%02x" % ord(c)) - - r = '"%s"' % "".join(s) - return item_length, r + s += "\\%02x" % ord(c) + s += '"' + return [self.ref + " = " + s] -class VoidArrayNode(ConstantLLVMNode): +class VoidArrayNode(ArrayNode): __slots__ = "db value ref".split() def __init__(self, db, value): @@ -107,6 +87,3 @@ prefix = 'arrayinstance_Void' name = '' self.ref = self.make_ref(prefix, name) - - def constantvalue(self): - return "{ int } {int %s}" % len(self.value.items) Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Tue Oct 18 11:04:11 2005 @@ -36,9 +36,6 @@ def newline(self): self.append("") - def label(self, name): - self.append("case %d:" % name, 3) - def openblock(self, name): self.append("case %d:" % name, 3) self._currentblock = name @@ -48,34 +45,13 @@ self.append('break') self.skip_closeblock(False) - def globalinstance(self, name, typeanddata): - #self.append('%s = %s' % (name, typeanddata[1:].split('{')[1][:-1]), 0) - lines = typeanddata.split('\n') - #self.llvm("%s = global %s" % (name, lines[0]), 0) - self.append("%s = %s" % (name, lines[0]), 0) - for line in lines[1:]: - self.llvm(line, 0) - - def structdef(self, name, typereprs): - #self.llvm("%s = type { %s }" %(name, ", ".join(typereprs)), 0) - pass - - def arraydef(self, name, lentype, typerepr): - #self.llvm("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr), 0) - pass - - def funcdef(self, name, rettyperepr, argtypereprs): - #self.llvm("%s = type %s (%s)" % (name, rettyperepr, - # ", ".join(argtypereprs)), 0) - pass + def globalinstance(self, lines=[]): + for line in lines: + self.append(line, 0) def declare(self, decl): self.append(decl, 0) - def startimpl(self): - #self.llvm("implementation", 0) - pass - def _goto_block(self, block, indentation_level=4): if block == self._currentblock + 1: self._skip_closeblock = True @@ -155,18 +131,25 @@ def neg(self, targetvar, source): self.append('%(targetvar)s = -%(source)s' % locals()) - def call(self, targetvar, returntype, functionref, argrefs, argtypes, label=None, except_label=None): - #args = ", ".join(["%s %s" % item for item in zip(argtypes, argrefs)]) - args = ", ".join(argrefs) - if except_label: - self.js.exceptionpolicy.invoke(self, targetvar, returntype, functionref, args, label, except_label) + def call(self, targetvar, functionref, argrefs, label=None, exception_exits=[]): + if exception_exits: + assert label is not None + self.append('try {') + indentation_level = 5 else: - if returntype == 'void': - #self.llvm("call void %s(%s)" % (functionref, args)) - self.append('%s(%s)' % (functionref, args)) - else: - #self.llvm("%s = call %s %s(%s)" % (targetvar, returntype, functionref, args)) - self.append('%s = %s(%s)' % (targetvar, functionref, args)) + assert label is None + indentation_level = 4 + + args = ", ".join(argrefs) + self.append('%s = %s(%s)' % (targetvar, functionref, args), indentation_level) + + if exception_exits: + self.append('block = %d' % label, indentation_level) + self.append('} catch (e) {') + for exception in exception_exits: + self.comment('exception.target = %s' % str(exception.target), indentation_level) + self.append('block = %d' % label, indentation_level) #XXX temp + self.append('}') def cast(self, targetvar, fromtype, fromvar, targettype): if fromtype == 'void' and targettype == 'void': @@ -182,15 +165,14 @@ else: self.llvm("%(targetvar)s = cast %(fromtype)s %(fromvar)s to %(targettype)s" % locals()) - def malloc(self, targetvar, type_, size=1, atomic=False): - for s in self.js.gcpolicy.malloc(targetvar, type_, size, atomic, 'word', 'uword').split('\n'): - self.append(s) + def malloc(self, targetvar, type_): + self.append('%(targetvar)s = new %(type_)s()' % locals()) def getelementptr(self, targetvar, type, typevar, *indices): res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, word 0, " % locals() res += ", ".join(["%s %s" % (t, i) for t, i in indices]) self.llvm(res) - + #res = "%(targetvar)s = %(typevar)s" % locals() #res += ''.join(['[%s]' % i for t, i in indices]) #self.append(res) @@ -205,9 +187,3 @@ res += ''.join(['[%s]' % index for index in destindices]) res += " = %(srcvar)s" % locals() self.append(res) - - def debugcomment(self, tempname, len, tmpname): - res = "%s = call %(word)s (sbyte*, ...)* printf(" % locals() - res += "sbyte* getelementptr ([%s x sbyte]* %s, word 0, word 0) )" % locals() - res = res % (tmpname, len, tmpname) - self.llvm(res) Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Tue Oct 18 11:04:11 2005 @@ -31,42 +31,6 @@ self._pendingsetup = [] self._tmpcount = 1 - # debug operation comments - self._opcomments = {} - - #_______for debugging llvm code_________________________ - - def add_op2comment(self, lenofopstr, op): - """ internal method for adding comments on each operation """ - tmpname = self.repr_tmpvar() + ".comment" - self._opcomments[op] = (lenofopstr, tmpname) - return tmpname - - def get_op2comment(self, op): - """ internal method for adding comments on each operation """ - return self._opcomments.get(op, None) - - #_______debuggging______________________________________ - - def dump_pbcs(self): - r = "" - for k, v in self.obj2node.iteritems(): - - if isinstance(k, lltype.LowLevelType): - continue - - assert isinstance(lltype.typeOf(k), lltype.ContainerType) - # 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 - #_______setting up and preperation______________________________ def create_constant_node(self, type_, value): @@ -110,40 +74,6 @@ self.obj2node[key] = node self._pendingsetup.append(node) - #def prepare_type(self, type_): - # return #forget about the types in Javascript - # - # #if type_ in self.obj2node: - # # return - # #if isinstance(type_, lltype.Primitive): - # # pass - # #elif isinstance(type_, lltype.Ptr): - # # self.prepare_type(type_.TO) - # # - # #elif isinstance(type_, lltype.Struct): - # # if type_._arrayfld: - # # self.addpending(type_, StructVarsizeTypeNode(self, type_)) - # # else: - # # self.addpending(type_, StructTypeNode(self, type_)) - # #elif isinstance(type_, lltype.FuncType): - # # self.addpending(type_, FuncTypeNode(self, type_)) - # # - # #elif isinstance(type_, lltype.Array): - # # if type_.OF is lltype.Void: - # # self.addpending(type_, VoidArrayTypeNode(self, type_)) - # # else: - # # self.addpending(type_, ArrayTypeNode(self, type_)) - # # - # #elif isinstance(type_, lltype.OpaqueType): - # # self.addpending(type_, OpaqueTypeNode(self, type_)) - # # - # #else: - # # assert False, "need to prepare typerepr %s %s" % (type_, type(type_)) - # - #def prepare_type_multi(self, types): - # for type_ in types: - # self.prepare_type(type_) - def prepare_constant(self, type_, value): if isinstance(type_, lltype.Primitive): #log.prepareconstant(value, "(is primitive)") @@ -163,9 +93,6 @@ # we can share data via pointers if value not in self.obj2node: self.addpending(value, self.create_constant_node(type_, value)) - - # always add type (it is safe) - #self.prepare_type(type_) def prepare_arg_value(self, const_or_var): """if const_or_var is not already in a dictionary self.obj2node, @@ -227,9 +154,18 @@ assert isinstance(arg, Variable) return str(arg) + def repr_type(self, arg): + try: + node = self.obj2node.get(arg.value._obj) + if isinstance(node, ArrayNode): + return 'Array' + except: + pass + return 'Object' + def repr_concretetype(self, ct): #used by casts try: - return self.obj2node[ct].ref + return self.obj2node[ct].ref except KeyError: if isinstance(ct, lltype.Primitive): return self.primitives[ct] @@ -249,16 +185,14 @@ return None, repr elif isinstance(type_, lltype.Ptr): - toptr = '' #self.repr_type(type_) value = value._obj # special case, null pointer if value is None: - return None, "%s null" % (toptr,) + return None, "null" node = self.obj2node[value] - ref = node.get_pbcref(toptr) - return node, "%s %s" % (toptr, ref) + return node, node.get_ref() elif isinstance(type_, lltype.Array) or isinstance(type_, lltype.Struct): node = self.obj2node[value] @@ -319,6 +253,14 @@ # __________________________________________________________ # 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 get_childref(self, parent, child): node = self.obj2node[parent] return node.get_childref(child) Modified: pypy/dist/pypy/translator/js/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/js/extfuncnode.py (original) +++ pypy/dist/pypy/translator/js/extfuncnode.py Tue Oct 18 11:04:11 2005 @@ -12,19 +12,19 @@ name = value._callable.__name__ assert name.startswith("ll") name = "LL" + name[2:] - self.ref = self.make_ref("%", name) + self.ref = self.make_ref("", name) self.used_external_functions[self.ref] = True - def getdecl(self): - T = self.value._TYPE - 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 - - def writedecl(self, codewriter): - codewriter.declare(self.getdecl()) - - def writeglobalconstants(self, codewriter): - pass + #def getdecl(self): + # T = self.value._TYPE + # 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 + # + #def writedecl(self, codewriter): + # codewriter.declare(self.getdecl()) + # + #def writeglobalconstants(self, codewriter): + # pass Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Tue Oct 18 11:04:11 2005 @@ -5,9 +5,6 @@ from pypy.rpython import lltype from pypy.translator.js.node import LLVMNode, ConstantLLVMNode from pypy.translator.js.opwriter import OpWriter -#from pypy.translator.js.backendopt.removeexcmallocs import remove_exception_mallocs -#from pypy.translator.js.backendopt.mergemallocs import merge_mallocs -from pypy.translator.unsimplify import remove_double_links from pypy.translator.js.log import log log = log.funcnode @@ -22,12 +19,6 @@ self.ref = self.make_ref(pypy_prefix, value.graph.name) self.graph = value.graph - self.db.genllvm.exceptionpolicy.transform(self.db.translator, self.graph) - #remove_exception_mallocs(self.db.translator, self.graph, self.ref) - #merge_mallocs(self.db.translator, self.graph, self.ref) - - #remove_double_links(self.db.translator, self.graph) - def __str__(self): return "" %(self.ref,) @@ -72,33 +63,6 @@ codewriter.closeblock() codewriter.closefunc() - def writecomments(self, codewriter): - """ write operations strings for debugging purposes. """ - blocks = [x for x in flatten(self.graph) if isinstance(x, Block)] - for block in blocks: - for op in block.operations: - strop = str(op) + "\n\x00" - l = len(strop) - if strop.find("direct_call") == -1: - continue - tempname = self.db.add_op2comment(l, op) - 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): - pass - # ______________________________________________________________________ # writing helpers for entry points @@ -134,15 +98,6 @@ else: last_op_index = None for op_index, op in enumerate(block.operations): - 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. @@ -164,4 +119,7 @@ codewriter.ret( self.db.repr_arg(block.inputargs[0]) ) def write_exceptblock(self, codewriter, block): - self.db.genllvm.exceptionpolicy.write_exceptblock(self, codewriter, block) + #self.db.genllvm.exceptionpolicy.write_exceptblock(self, codewriter, block) + codewriter.comment('XXX TODO write_exceptblock') + codewriter.append('throw "Pypy exception"') + codewriter.skip_closeblock() Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Tue Oct 18 11:04:11 2005 @@ -20,17 +20,13 @@ from pypy.translator.js.node import LLVMNode from pypy.translator.js.database import Database from pypy.translator.js.codewriter import CodeWriter -from pypy.translator.js.gc import GcPolicy -from pypy.translator.js.exception import ExceptionPolicy from pypy.translator.js.log import log class JS(object): # JS = Javascript - def __init__(self, translator, function=None, gcpolicy=None, exceptionpolicy=None, debug=False): + def __init__(self, translator, function=None, debug=False): self.db = Database(self, translator) self.translator = translator - self.gcpolicy = GcPolicy.new(gcpolicy) - self.exceptionpolicy = ExceptionPolicy.new(exceptionpolicy) LLVMNode.reset_nodename_count() #extfuncnode.ExternalFuncNode.used_external_functions = {} self.debug = debug # for debug we create comments of every operation that may be executed Modified: pypy/dist/pypy/translator/js/node.py ============================================================================== --- pypy/dist/pypy/translator/js/node.py (original) +++ pypy/dist/pypy/translator/js/node.py Tue Oct 18 11:04:11 2005 @@ -44,13 +44,11 @@ def writedecl(self, codewriter): """ write function forward declarations. """ - def writecomments(self, codewriter): - """ write operations strings for debugging purposes. """ - # __________________ after "implementation" ____________________ def writeimpl(self, codewriter): """ write function implementations. """ + class ConstantLLVMNode(LLVMNode): __slots__ = "".split() @@ -58,13 +56,9 @@ """ 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") + return [] # ______________________________________________________________________ # entry points from genllvm @@ -72,4 +66,4 @@ def writeglobalconstants(self, codewriter): p, c = lltype.parentlink(self.value) if p is None: - codewriter.globalinstance(self.ref, self.constantvalue()) + codewriter.globalinstance( self.constantvalue() ) Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Tue Oct 18 11:04:11 2005 @@ -132,10 +132,8 @@ def int_abs(self, op): #ExternalFuncNode.used_external_functions[functionref] = True self.codewriter.call(self.db.repr_arg(op.result), - self.db.repr_arg_type(op.result), 'Math.abs', - [self.db.repr_arg(op.args[0])], - [self.db.repr_arg_type(op.args[0])]) + [self.db.repr_arg(op.args[0])]) float_abs = int_abs def int_pow(self, op): @@ -240,11 +238,9 @@ if arg.concretetype is not lltype.Void] assert len(op_args) >= 1 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:]) - self.codewriter.call(targetvar,returntype,functionref,argrefs,argtypes) + self.codewriter.call(targetvar, functionref, argrefs) def invoke(self, op): op_args = [arg for arg in op.args @@ -254,7 +250,7 @@ functionref = self.db.repr_arg(op_args[0]) else: #operation opname = op.opname.split(':',1)[1] - op_args = ['%' + opname] + op_args + op_args = [opname] + op_args functionref = op_args[0] if functionref in extfunctions: ExternalFuncNode.used_external_functions[functionref] = True @@ -263,7 +259,7 @@ self.codewriter.comment('XXX: Error: ' + msg) # XXX commented out for testing #assert functionref in extfunctions, msg - + assert len(op_args) >= 1 # at least one label and one exception label assert len(self.block.exits) >= 2 @@ -272,18 +268,16 @@ assert link.exitcase is None targetvar = self.db.repr_arg(op.result) - returntype = self.db.repr_arg_type(op.result) + #returntype = self.db.repr_arg_type(op.result) argrefs = self.db.repr_arg_multi(op_args[1:]) - argtypes = self.db.repr_arg_type_multi(op_args[1:]) + #argtypes = self.db.repr_arg_type_multi(op_args[1:]) none_label = self.node.blockindex[link.target] block_label = self.node.blockindex[self.block] - exc_label = 10000 + block_label #_exception_label + #exc_label = block_label #_exception_label - #if self.db.is_function_ptr(op.result): #use longhand form - # returntype = "%s (%s)*" % (returntype, ", ".join(argtypes)) - self.codewriter.call(targetvar, returntype, functionref, argrefs, - argtypes, none_label, exc_label) + self.codewriter.call(targetvar, functionref, argrefs, none_label, self.block.exits[1:]) + return e = self.db.translator.rtyper.getexceptiondata() pypy_prefix = '' #pypy_ @@ -295,7 +289,7 @@ e.lltype_of_exception_value.TO.__name__ + '*') - self.codewriter.label(exc_label) + self.codewriter.openblock(exc_label) exc_found_labels, last_exception_type = [], None catch_all = False @@ -306,27 +300,29 @@ current_exception_type = etype.get_ref() target = self.node.blockindex[link.target] #exc_found_label = block_label + '_exception_found_branchto_' + target - exc_found_label = '%d_exception_found_branchto_%d' % (block_label, target) + exc_found_label = target #'%d_exception_found_branchto_%d' % (block_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 - if name.startswith('last_exception_'): - last_exc_type_var = name - if name.startswith('last_exc_value_'): - last_exc_value_var = name + #XXX refactor this + #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 + # 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:] + not_this_exception_label = str(block_label) + '_not_exception_' + etype.ref[1:] if current_exception_type.find('getelementptr') == -1: #catch all (except:) catch_all = True - self.codewriter.br_uncond(exc_found_label) + self.codewriter.comment('br_uncond %s' % exc_found_label) + #self.codewriter.br_uncond(exc_found_label) else: #catch specific exception (class) type if not last_exception_type: #load pointer only once last_exception_type = self.db.repr_tmpvar() @@ -334,23 +330,22 @@ 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.openblock(not_this_exception_label) - ep = self.codewriter.genllvm.exceptionpolicy + ep = self.codewriter.js.exceptionpolicy if not catch_all: ep.reraise(self.node, self.codewriter) - ep.fetch_exceptions(self.codewriter, exc_found_labels, lltype_of_exception_type, lltype_of_exception_value) + ep.fetch_exceptions(self.codewriter,self.block,exc_found_labels,lltype_of_exception_type,lltype_of_exception_value) def malloc(self, op): arg_type = op.args[0].value targetvar = self.db.repr_arg(op.result) - type_ = '' #self.db.repr_type(arg_type) - self.codewriter.malloc(targetvar, type_, atomic=arg_type._is_atomic()) + type_ = self.db.repr_type(arg_type) + self.codewriter.malloc(targetvar, type_) malloc_exception = malloc malloc_varsize = malloc Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Tue Oct 18 11:04:11 2005 @@ -90,7 +90,13 @@ name = _rename_reserved_keyword(name) var = (name, str(value)) vars.append(var) - return "({%s})" % ", ".join(["%s:%s" % var for var in vars]) + lines = [] + for var in vars: + name, value = var + #s = "({%s})" % ", ".join(["%s:%s" % var for var in vars]) + line = "%s.%s = %s" % (self.ref, name, value) + lines.append(line) + return lines #values = self._getvalues() #all_values = ",\n ".join(values) From ericvrp at codespeak.net Tue Oct 18 11:11:39 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Tue, 18 Oct 2005 11:11:39 +0200 (CEST) Subject: [pypy-svn] r18730 - pypy/dist/pypy/translator/js Message-ID: <20051018091139.46C2327B42@code1.codespeak.net> Author: ericvrp Date: Tue Oct 18 11:11:38 2005 New Revision: 18730 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/node.py pypy/dist/pypy/translator/js/structnode.py Log: Removed slots and some caching. I don't want to see that kind of code before things really start working! Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Tue Oct 18 11:11:38 2005 @@ -11,8 +11,6 @@ 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 @@ -59,8 +57,6 @@ class StrArrayNode(ArrayNode): - __slots__ = "".split() - printables = dict([(ord(i), None) for i in ("0123456789abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + @@ -78,8 +74,6 @@ class VoidArrayNode(ArrayNode): - __slots__ = "db value ref".split() - def __init__(self, db, value): assert isinstance(lltype.typeOf(value), lltype.Array) self.db = db Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Tue Oct 18 11:11:38 2005 @@ -10,8 +10,6 @@ class FuncNode(ConstantLLVMNode): - __slots__ = "db value ref graph blockindex".split() - def __init__(self, db, value): self.db = db self.value = value Modified: pypy/dist/pypy/translator/js/node.py ============================================================================== --- pypy/dist/pypy/translator/js/node.py (original) +++ pypy/dist/pypy/translator/js/node.py Tue Oct 18 11:11:38 2005 @@ -4,8 +4,6 @@ _nodename_count = {} class LLVMNode(object): - __slots__ = "".split() - def reset_nodename_count(): global _nodename_count _nodename_count = {} @@ -50,8 +48,6 @@ class ConstantLLVMNode(LLVMNode): - __slots__ = "".split() - def get_ref(self): """ Returns a reference as used for operations in blocks. """ return self.ref Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Tue Oct 18 11:11:38 2005 @@ -17,8 +17,6 @@ a struct, pointer to struct/array """ - __slots__ = "db value structtype ref _get_ref_cache _get_types".split() - def __init__(self, db, value): self.db = db self.value = value @@ -26,7 +24,6 @@ prefix = 'structinstance_' name = str(value).split()[1] self.ref = self.make_ref(prefix, name) - self._get_ref_cache = None self._get_types = self._compute_types() def __str__(self): @@ -72,14 +69,11 @@ def get_ref(self): """ Returns a reference as used for operations in blocks. """ - if self._get_ref_cache: - return self._get_ref_cache p, c = lltype.parentlink(self.value) if p is None: ref = self.ref else: ref = self.db.get_childref(p, c) - self._get_ref_cache = ref return ref def constantvalue(self): @@ -143,16 +137,12 @@ super(StructVarsizeNode, self).setup() #def get_typerepr(self): - # try: - # return self._get_typerepr_cache - # except: - # # last type is a special case and need to be worked out recursively - # types = self._get_types[:-1] - # types_repr = [self.db.repr_type(T) for name, T in types] - # types_repr.append(self._get_lastnode().get_typerepr()) - # result = "{%s}" % ", ".join(types_repr) - # self._get_typerepr_cache = result - # return result + # # last type is a special case and need to be worked out recursively + # types = self._get_types[:-1] + # types_repr = [self.db.repr_type(T) for name, T in types] + # types_repr.append(self._get_lastnode().get_typerepr()) + # result = "{%s}" % ", ".join(types_repr) + # return result def get_ref(self): return self.ref From arigo at codespeak.net Tue Oct 18 11:19:33 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 11:19:33 +0200 (CEST) Subject: [pypy-svn] r18731 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051018091933.C61C727B42@code1.codespeak.net> Author: arigo Date: Tue Oct 18 11:19:32 2005 New Revision: 18731 Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/rpbc.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: Mangle attribute and method names to avoid clashes with attributes like _TYPE. Temporarily, it looks like a good idea to mangle names systematically to trap bugs related to a confusion between mangled and non-mangled names. Later a more subtle mangling that doesn't modify common names would be better. Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue Oct 18 11:19:32 2005 @@ -21,6 +21,17 @@ # FIXME pass + +def mangle(name): + # XXX temporary: for now it looks like a good idea to mangle names + # systematically to trap bugs related to a confusion between mangled + # and non-mangled names + return 'o' + name + +def unmangle(mangled): + assert mangled.startswith('o') + return mangled[1:] + class InstanceRepr(AbstractInstanceRepr): def __init__(self, rtyper, classdef, does_need_gc=True): AbstractInstanceRepr.__init__(self, rtyper, classdef) @@ -46,14 +57,20 @@ allclassattributes = {} fields = {} + fielddefaults = {} attrs = self.classdef.attrs.items() for name, attrdef in attrs: if not attrdef.readonly: + mangled = mangle(name) repr = self.rtyper.getrepr(attrdef.s_value) - allfields[name] = repr + allfields[mangled] = repr oot = repr.lowleveltype - fields[name] = oot + fields[mangled] = oot + try: + fielddefaults[mangled] = getattr(self.classdef.cls, name) + except AttributeError: + pass ootype.addFields(self.lowleveltype, fields) @@ -71,19 +88,20 @@ impl = self.classdef.cls.__dict__[name] except KeyError: continue + mangled = mangle(name) if classrepr.prepare_method(attrdef.s_value) is not None: # a regular method f, inputs, ret = getsignature(self.rtyper, impl) M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) - m = ootype.meth(M, _name=name, _callable=impl, + m = ootype.meth(M, _name=mangled, _callable=impl, graph=f.graph) - methods[name] = m - allmethods[name] = True + methods[mangled] = m + allmethods[mangled] = True else: # a non-method class attribute - allclassattributes[name] = True + allclassattributes[mangled] = True if not attrdef.s_value.is_constant(): - classattributes[name] = attrdef.s_value, impl + classattributes[mangled] = attrdef.s_value, impl ootype.addMethods(self.lowleveltype, methods) self.allfields = allfields @@ -94,64 +112,66 @@ # convert_const can require 'self' to be fully initialized. # step 2: provide default values for fields - for name, oot in fields.items(): - try: - impl = getattr(self.classdef.cls, name) - except AttributeError: - pass - else: - r = allfields[name] - oovalue = r.convert_const(impl) - ootype.addFields(self.lowleveltype, {name: (oot, oovalue)}) + for mangled, impl in fielddefaults.items(): + oot = fields[mangled] + r = allfields[mangled] + oovalue = r.convert_const(impl) + ootype.addFields(self.lowleveltype, {mangled: (oot, oovalue)}) # step 3: provide accessor methods for class attributes that are # really overridden in subclasses - for name, (s_value, impl) in classattributes.items(): + for mangled, (s_value, impl) in classattributes.items(): r = self.rtyper.getrepr(s_value) oovalue = r.convert_const(impl) - m = self.attach_class_attr_accessor(name, oovalue, r.lowleveltype) + m = self.attach_class_attr_accessor(mangled, oovalue, + r.lowleveltype) - def attach_class_attr_accessor(self, name, oovalue, oovaluetype): + def attach_class_attr_accessor(self, mangled, oovalue, oovaluetype): def ll_getclassattr(self): return oovalue - ll_getclassattr = func_with_new_name(ll_getclassattr, 'll_get_' + name) + ll_getclassattr = func_with_new_name(ll_getclassattr, + 'll_get_' + mangled) sm = self.rtyper.annotate_helper(ll_getclassattr, [self.lowleveltype]) M = ootype.Meth([], oovaluetype) - m = ootype.meth(M, _name=name, _callable=ll_getclassattr, + m = ootype.meth(M, _name=mangled, _callable=ll_getclassattr, graph=sm.graph) - ootype.addMethods(self.lowleveltype, {name: m}) + ootype.addMethods(self.lowleveltype, {mangled: m}) def rtype_getattr(self, hop): - vlist = hop.inputargs(self, ootype.Void) - attr = hop.args_s[1].const + v_inst, _ = hop.inputargs(self, ootype.Void) s_inst = hop.args_s[0] - if attr in self.allfields: + attr = hop.args_s[1].const + mangled = mangle(attr) + v_attr = hop.inputconst(ootype.Void, mangled) + if mangled in self.allfields: # regular instance attributes - self.lowleveltype._check_field(attr) - return hop.genop("oogetfield", vlist, + self.lowleveltype._check_field(mangled) + return hop.genop("oogetfield", [v_inst, v_attr], resulttype = hop.r_result.lowleveltype) - elif attr in self.allmethods: + elif mangled in self.allmethods: # special case for methods: represented as their 'self' only # (see MethodsPBCRepr) - return hop.r_result.get_method_from_instance(self, vlist[0], + return hop.r_result.get_method_from_instance(self, v_inst, hop.llops) - elif attr in self.allclassattributes: + elif mangled in self.allclassattributes: # class attributes if hop.s_result.is_constant(): oovalue = hop.r_result.convert_const(hop.s_result.const) return hop.inputconst(hop.r_result, oovalue) else: - cname = hop.inputconst(ootype.Void, attr) - return hop.genop("oosend", [cname, vlist[0]], + cname = hop.inputconst(ootype.Void, mangled) + return hop.genop("oosend", [cname, v_inst], resulttype = hop.r_result.lowleveltype) else: raise TyperError("no attribute %r on %r" % (attr, self)) def rtype_setattr(self, hop): attr = hop.args_s[1].const - self.lowleveltype._check_field(attr) - vlist = hop.inputargs(self, ootype.Void, hop.args_r[2]) - return hop.genop('oosetfield', vlist) + mangled = mangle(attr) + self.lowleveltype._check_field(mangled) + v_inst, _, v_newval = hop.inputargs(self, ootype.Void, hop.args_r[2]) + v_attr = hop.inputconst(ootype.Void, mangled) + return hop.genop('oosetfield', [v_inst, v_attr, v_newval]) def convert_const(self, value): if value is None: @@ -189,7 +209,8 @@ def initialize_prebuilt_instance(self, value, result): # then add instance attributes from this level - for name, (oot, default) in self.lowleveltype._allfields().items(): + for mangled, (oot, default) in self.lowleveltype._allfields().items(): + name = unmangle(mangled) if oot is ootype.Void: llattrvalue = None elif name == '_hash_cache_': # hash() support @@ -201,8 +222,8 @@ warning("prebuilt instance %r has no attribute %r" % ( value, name)) continue - llattrvalue = self.allfields[name].convert_const(attrvalue) - setattr(result, name, llattrvalue) + llattrvalue = self.allfields[mangled].convert_const(attrvalue) + setattr(result, mangled, llattrvalue) class __extend__(pairtype(InstanceRepr, InstanceRepr)): Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Tue Oct 18 11:19:32 2005 @@ -1,7 +1,7 @@ from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr from pypy.rpython.rclass import rtype_new_instance from pypy.rpython.ootypesystem import ootype -from pypy.rpython.ootypesystem.rclass import InstanceRepr +from pypy.rpython.ootypesystem.rclass import InstanceRepr, mangle from pypy.annotation.pairtype import pairtype class ClassesPBCRepr(AbstractClassesPBCRepr): @@ -18,7 +18,8 @@ def rtype_simple_call(self, hop): vlist = hop.inputargs(self, *hop.args_r[1:]) - cname = hop.inputconst(ootype.Void, self.methodname) + mangled = mangle(self.methodname) + cname = hop.inputconst(ootype.Void, mangled) return hop.genop("oosend", [cname]+vlist, resulttype = hop.r_result.lowleveltype) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Tue Oct 18 11:19:32 2005 @@ -178,3 +178,16 @@ return x.a res = interpret(dummyfn, [], type_system='ootype') assert res == 4 + +def test_name_clashes(): + class NameClash1(object): + def _TYPE(self): + return 6 + def dummyfn(n): + x = NameClash1() + y = EmptyBase() + y._TYPE = n+1 + return x._TYPE() * y._TYPE + res = interpret(dummyfn, [6], type_system='ootype') + assert res == 42 + From arigo at codespeak.net Tue Oct 18 11:53:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 11:53:29 +0200 (CEST) Subject: [pypy-svn] r18732 - pypy/dist/pypy/rpython/ootypesystem/test Message-ID: <20051018095329.A320A27B3D@code1.codespeak.net> Author: arigo Date: Tue Oct 18 11:53:29 2005 New Revision: 18732 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: Adding a test from test_rclass that passes. Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Tue Oct 18 11:53:29 2005 @@ -142,6 +142,16 @@ res = interpret(dummyfn, [], type_system='ootype') assert res == 6 +def test_prebuilt_instances_with_void(): + def marker(): + return 42 + a = EmptyBase() + a.nothing_special = marker + def dummyfn(): + return a.nothing_special() + res = interpret(dummyfn, [], type_system='ootype') + assert res == 42 + class HasClassAttr(object): a = 3 def f(self, n): From arigo at codespeak.net Tue Oct 18 12:14:15 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 12:14:15 +0200 (CEST) Subject: [pypy-svn] r18733 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051018101415.CE44827B48@code1.codespeak.net> Author: arigo Date: Tue Oct 18 12:14:14 2005 New Revision: 18733 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: ootyper: boolean checks on oo instances returns True/False for non-null/null instances. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Oct 18 12:14:14 2005 @@ -652,6 +652,10 @@ def op_oodowncast(self, INST, inst): return ootype.oodowncast(INST, inst) + def op_oononnull(self, inst): + assert isinstance(inst, ootype._instance) + return bool(inst) + # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help # for failing tests Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Oct 18 12:14:14 2005 @@ -168,6 +168,9 @@ self.__dict__[name] = value + def __nonzero__(self): + return True # better be explicit -- overridden in _null_instance + class _null_instance(_instance): def __init__(self, INSTANCE): @@ -186,6 +189,9 @@ raise RuntimeError("Assignment to field in null object") + def __nonzero__(self): + return False + class _callable(object): def __init__(self, TYPE, **attrs): Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue Oct 18 12:14:14 2005 @@ -173,6 +173,10 @@ v_attr = hop.inputconst(ootype.Void, mangled) return hop.genop('oosetfield', [v_inst, v_attr, v_newval]) + def rtype_is_true(self, hop): + vinst, = hop.inputargs(self) + return hop.genop('oononnull', [vinst], resulttype=ootype.Bool) + def convert_const(self, value): if value is None: return null(self.lowleveltype) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Tue Oct 18 12:14:14 2005 @@ -201,3 +201,14 @@ res = interpret(dummyfn, [6], type_system='ootype') assert res == 42 +def test_null_instance(): + def dummyfn(flag): + if flag: + x = EmptyBase() + else: + x = None + return not x + res = interpret(dummyfn, [True], type_system='ootype') + assert res is False + res = interpret(dummyfn, [False], type_system='ootype') + assert res is True From arigo at codespeak.net Tue Oct 18 12:32:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 12:32:44 +0200 (CEST) Subject: [pypy-svn] r18734 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051018103244.BB05C27B48@code1.codespeak.net> Author: arigo Date: Tue Oct 18 12:32:43 2005 New Revision: 18734 Added: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: ootyper: isinstance() support (including much confusion about ootype.Class, Instance, _class, _instance, _INSTANCE, etc.) Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Oct 18 12:32:43 2005 @@ -656,6 +656,9 @@ assert isinstance(inst, ootype._instance) return bool(inst) + def op_instanceof(self, inst, INST): + return ootype.instanceof(inst, INST) + # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help # for failing tests Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Oct 18 12:32:43 2005 @@ -255,7 +255,11 @@ return INSTANCE._null def instanceof(inst, INSTANCE): - return isSubclass(inst._TYPE, INSTANCE) + # this version of instanceof() accepts a NULL instance and always + # returns False in this case. + assert isinstance(inst, _instance) + assert isinstance(INSTANCE, Instance) + return bool(inst) and isSubclass(inst._TYPE, INSTANCE) def classof(inst): return runtimeClass(inst._TYPE) Added: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Tue Oct 18 12:32:43 2005 @@ -0,0 +1,28 @@ +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.ootypesystem import rclass +from pypy.objspace.flow.model import Constant + + +def rtype_builtin_isinstance(hop): + if hop.s_result.is_constant(): + return hop.inputconst(lltype.Bool, hop.s_result.const) + + if hop.args_s[1].is_constant() and hop.args_s[1].const == list: + if hop.args_s[0].knowntype != list: + raise TyperError("isinstance(x, list) expects x to be known statically to be a list or None") + raise TyperError("XXX missing impl of isinstance(x, list)") + + class_repr = rclass.get_type_repr(hop.rtyper) + instance_repr = hop.args_r[0] + assert isinstance(instance_repr, rclass.InstanceRepr) + + v_obj, v_cls = hop.inputargs(instance_repr, class_repr) + if isinstance(v_cls, Constant): + c_cls = hop.inputconst(ootype.Void, v_cls.value._INSTANCE) + return hop.genop('instanceof', [v_obj, c_cls], resulttype=ootype.Bool) + else: + raise TyperError("XXX missing impl of isinstance(x, variable)") + + +BUILTIN_TYPER = {} +BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Tue Oct 18 12:32:43 2005 @@ -1,6 +1,7 @@ +import types from pypy.rpython.rmodel import inputconst from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \ - getinstancerepr, getclassrepr + getinstancerepr, getclassrepr, get_type_repr from pypy.rpython.rpbc import getsignature from pypy.rpython.ootypesystem import ootype from pypy.annotation.pairtype import pairtype @@ -17,9 +18,19 @@ def _setup_repr(self): pass # not actually needed? - def convert_const(self): - # FIXME - pass + def convert_const(self, value): + if not isinstance(value, (type, types.ClassType)): + raise TyperError("not a class: %r" % (value,)) + try: + subclassdef = self.rtyper.annotator.getuserclasses()[value] + except KeyError: + raise TyperError("no classdef: %r" % (value,)) + if self.classdef is not None: + if self.classdef.commonbase(subclassdef) != self.classdef: + raise TyperError("not a subclass of %r: %r" % ( + self.classdef.cls, value)) + # + return getinstancerepr(self.rtyper, subclassdef).lowleveltype._class def mangle(name): @@ -179,7 +190,7 @@ def convert_const(self, value): if value is None: - return null(self.lowleveltype) + return ootype.null(self.lowleveltype) try: classdef = self.rtyper.annotator.getuserclasses()[value.__class__] except KeyError: Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Tue Oct 18 12:32:43 2005 @@ -212,3 +212,29 @@ assert res is False res = interpret(dummyfn, [False], type_system='ootype') assert res is True + +def test_isinstance(): + class A: + pass + 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) + res = interpret(f, [1], type_system='ootype') + assert res == 100 + res = interpret(f, [2], type_system='ootype') + assert res == 110 + res = interpret(f, [3], type_system='ootype') + assert res == 111 + res = interpret(f, [0], type_system='ootype') + assert res == 0 From arigo at codespeak.net Tue Oct 18 13:43:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 13:43:43 +0200 (CEST) Subject: [pypy-svn] r18735 - in pypy/extradoc/sprintinfo: . paris Message-ID: <20051018114343.9AB3527B53@code1.codespeak.net> Author: arigo Date: Tue Oct 18 13:43:42 2005 New Revision: 18735 Modified: pypy/extradoc/sprintinfo/Heidelberg-report.txt (props changed) pypy/extradoc/sprintinfo/paris/ (props changed) pypy/extradoc/sprintinfo/paris/stackless-discussion.txt (contents, props changed) pypy/extradoc/sprintinfo/paris/wp9_10_plan.txt (props changed) Log: fixeol Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/stackless-discussion.txt (original) +++ pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Tue Oct 18 13:43:42 2005 @@ -1,85 +1,85 @@ -==================================================== - Stackless / Continuation discussion group -==================================================== - -Bert Freudenberg, Jacob Hall?n, Adrien di Mascio, -Valentino Volonghi, Christian Tismer - -Introduction to current ideas ------------------------------- - -We had a small introduction about Stackless Python and -its implementation. We compared that to PyPy for similarities -and differences. - -The idea is to keep recursion and stack usage as an efficient -approach using the C compiler and current processor. -The whole problem of making PyPy stackless is solved by providing -RPython with a mechanism to unwind and save this stack structure. - -An implementation of an example was written by Armin. This -is thought as a template of how the generated code (c|sh)ould look like. - - -This approach supports - -- full continuations, because we can clone the saved block structures -- restartable exceptions (yet only at the RPython level) -- pickling program state -- unlimited recursion -- context switching -- garbage collection with explicit knowledge of all roots - - -General impressions --------------------- - -The proposed stackless extension of the existing framework -might be easier to implement than a new approach using -continuation passing style. But we might want to try -examples for both and compare performance. - -Needed independently of the backend: -being able to capture variables of a block. -This could work on the annotated flowgraph, but probably makes -more sense after all the backend optimizations. It is still -the same for all backends. - -Needed action: -Find the set of necessary structures to describe the status of all blocks. -Generate types for all the variants of blocks. The concrete implementation -may vary. The current simple approach is a block number that encodes -function, arity, return type of the function and relative block -number. Different encodings are possible and may vary per backend. -(In assembly, one would probably add descriptor info right before -the function entrypoint...) - -Aliveness considerations, partially related to the backend: -The state blocks take over the role of the stack. The stack may -instead be considered as a cache for the state blocks. State -blocks are actually a synonym for continuations. - - -Backend: - -Tasks for implementation: - -- generating the structures for saving the blocks -- generate extra code for function re-entry -- write extra support for detecting stack overflows. - - + have extra info about the stack size of every function. - -Thinking about re-use of the existing exception handling code, -which is there for every function call. Adding yet another case -might be cheap. See if this is simpler or more complex -than using extra variables. - -Observations: -------------- - -We can use this mechanism to produce restartable exceptions. But this -is not about Python-level exceptions without further support. - -This approach appears to give us full continuations for free. - +==================================================== + Stackless / Continuation discussion group +==================================================== + +Bert Freudenberg, Jacob Hall?n, Adrien di Mascio, +Valentino Volonghi, Christian Tismer + +Introduction to current ideas +------------------------------ + +We had a small introduction about Stackless Python and +its implementation. We compared that to PyPy for similarities +and differences. + +The idea is to keep recursion and stack usage as an efficient +approach using the C compiler and current processor. +The whole problem of making PyPy stackless is solved by providing +RPython with a mechanism to unwind and save this stack structure. + +An implementation of an example was written by Armin. This +is thought as a template of how the generated code (c|sh)ould look like. + + +This approach supports + +- full continuations, because we can clone the saved block structures +- restartable exceptions (yet only at the RPython level) +- pickling program state +- unlimited recursion +- context switching +- garbage collection with explicit knowledge of all roots + + +General impressions +-------------------- + +The proposed stackless extension of the existing framework +might be easier to implement than a new approach using +continuation passing style. But we might want to try +examples for both and compare performance. + +Needed independently of the backend: +being able to capture variables of a block. +This could work on the annotated flowgraph, but probably makes +more sense after all the backend optimizations. It is still +the same for all backends. + +Needed action: +Find the set of necessary structures to describe the status of all blocks. +Generate types for all the variants of blocks. The concrete implementation +may vary. The current simple approach is a block number that encodes +function, arity, return type of the function and relative block +number. Different encodings are possible and may vary per backend. +(In assembly, one would probably add descriptor info right before +the function entrypoint...) + +Aliveness considerations, partially related to the backend: +The state blocks take over the role of the stack. The stack may +instead be considered as a cache for the state blocks. State +blocks are actually a synonym for continuations. + + +Backend: + +Tasks for implementation: + +- generating the structures for saving the blocks +- generate extra code for function re-entry +- write extra support for detecting stack overflows. + + + have extra info about the stack size of every function. + +Thinking about re-use of the existing exception handling code, +which is there for every function call. Adding yet another case +might be cheap. See if this is simpler or more complex +than using extra variables. + +Observations: +------------- + +We can use this mechanism to produce restartable exceptions. But this +is not about Python-level exceptions without further support. + +This approach appears to give us full continuations for free. + From arigo at codespeak.net Tue Oct 18 13:45:20 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 13:45:20 +0200 (CEST) Subject: [pypy-svn] r18736 - pypy/dist/pypy/tool Message-ID: <20051018114520.685A827B55@code1.codespeak.net> Author: arigo Date: Tue Oct 18 13:45:19 2005 New Revision: 18736 Modified: pypy/dist/pypy/tool/fixeol Log: Apparently, un-Windowsifying the content of the file to fix end-of-lines always creates huge diffs. Strangely enough, svn diff doesn't list these lines as modified, but they still all show up in pypy-svn. Go figure. Modified: pypy/dist/pypy/tool/fixeol ============================================================================== --- pypy/dist/pypy/tool/fixeol (original) +++ pypy/dist/pypy/tool/fixeol Tue Oct 18 13:45:19 2005 @@ -39,13 +39,11 @@ if data != original: print "*"*30 print "---> %s <---" % path - print ("Hum, in order to run fixeol on this file " - "you need to be on the platform which " - "matches its line-endings. Modifying " - "the file content here would otherwise " - "lead to huge diffs!") + print ("WARNING: the file content was modified " + "by fixing the EOL style.") print "*"*30 - return False + #return False + return True return True def checkeolfile(path): From arigo at codespeak.net Tue Oct 18 14:30:47 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 14:30:47 +0200 (CEST) Subject: [pypy-svn] r18737 - pypy/extradoc/sprintinfo/paris Message-ID: <20051018123047.06DCB27B44@code1.codespeak.net> Author: arigo Date: Tue Oct 18 14:30:47 2005 New Revision: 18737 Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Log: tentative RPython interface to stackless frame chains. Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/stackless-discussion.txt (original) +++ pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Tue Oct 18 14:30:47 2005 @@ -83,3 +83,63 @@ This approach appears to give us full continuations for free. + +Exposing an interface to RPython +-------------------------------- + +Here is a tentative design of a minimal interface that might be good +enough to implement, say, app-level greenlets or tasklets as a mixed +module. + +We introduce an RPython type ``continuation`` and a built-in function +``yield_continuation()`` that work as follows (see example below): + +* The built-in function ``yield_continuation()`` causes the current + function's state to be captured in a new ``continuation`` object that + is returned to the parent. Only one frame, the current one, is + captured this way. The current frame is suspended and the caller + continues to run. + +* A ``continuation`` object can be jumped to by calling its ``switch()`` + method with no argument. + +* ``yield_continuation()`` and ``switch()`` themselves return a new + ``continuation`` object: the freshly captured state of the caller of + the source ``switch()`` that was just executed, or None in the case + described below. + +* ``yield_continuation()`` only works when called from a function whose + return type is precisely ``continuation``. In other words this + function must also contain a regular return statement that returns a + ``continuation``. When the captured continuation is later resumed and + the function eventually returns via this regular return statement, + then the returned ``continuation`` object designates the place where + execution should switch to (i.e. execution does not return to the + original caller). In such an implicit switch, a None is returned to + the ``switch()`` or ``yield_continuation()`` at place that we switch + to. + +* every continuation must be resumed once and only once. Not resuming + it at all causes a leak. Resuming it several times causes a crash. + +The following example would print the numbers from 1 to 7 in order:: + + def g(): + print 2 + cont_before_5 = yield_continuation() + print 4 + cont_before_7 = cont_before_5.switch() + print 6 + return cont_before_7 + + def f(): + print 1 + cont_before_4 = g() + print 3 + cont_before_6 = cont_before_4.switch() + print 5 + cont_after_return = cont_before_6.switch() + print 7 + assert cont_after_return is None + + f() From arigo at codespeak.net Tue Oct 18 14:44:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 14:44:29 +0200 (CEST) Subject: [pypy-svn] r18738 - pypy/extradoc/sprintinfo/paris Message-ID: <20051018124429.57E4727B57@code1.codespeak.net> Author: arigo Date: Tue Oct 18 14:44:28 2005 New Revision: 18738 Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Log: Comment about exceptions. Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/stackless-discussion.txt (original) +++ pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Tue Oct 18 14:44:28 2005 @@ -122,6 +122,10 @@ * every continuation must be resumed once and only once. Not resuming it at all causes a leak. Resuming it several times causes a crash. +* a function that called ``yield_continuation()`` should not raise. It + would have no implicit continuation to propagate the exception to. + That would be a crashingly bad idea. + The following example would print the numbers from 1 to 7 in order:: def g(): From cfbolz at codespeak.net Tue Oct 18 16:11:01 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 18 Oct 2005 16:11:01 +0200 (CEST) Subject: [pypy-svn] r18739 - pypy/dist/pypy/doc Message-ID: <20051018141101.2EC4227B46@code1.codespeak.net> Author: cfbolz Date: Tue Oct 18 16:11:00 2005 New Revision: 18739 Modified: pypy/dist/pypy/doc/news.txt Log: fixed newsitem to say tha the sprint is over Modified: pypy/dist/pypy/doc/news.txt ============================================================================== --- pypy/dist/pypy/doc/news.txt (original) +++ pypy/dist/pypy/doc/news.txt Tue Oct 18 16:11:00 2005 @@ -12,19 +12,24 @@ PyPy Sprint in Paris 10th-16th October 2005 ======================================================== -At the moment one of the biggest PyPy sprint ever is taking place: 18 people -are sitting in `Logilabs offices in Paris`_. We are happy to greet five new -developers to the PyPy Community! Currently we are focusing on implementing +The Paris sprint is over. We are all at home again and more or less exhausted. +The sprint attracted 18 participants and took place in +`Logilabs offices in Paris`_. We were happy to have five new +developers to the PyPy Community! The focus was on implementing `continuation-passing`_ style (stackless), making the translation process work for target languages with more powerful object systems and some tiny steps into the JIT_ direction. Michael and Carl have written -a `report about day one`_ and `one about day two and three`_. *(10/14/2005)* +a `report about day one`_ and `one about day two and three`_. +Together with Armin they wrote one about `the rest of the sprint`_ on the +way back. +*(10/18/2005)* .. _`Logilabs offices in Paris`: http://codespeak.net/pypy/extradoc/sprintinfo/paris-2005-sprint.html .. _JIT: http://en.wikipedia.org/wiki/Just-in-time_compilation .. _`continuation-passing`: http://en.wikipedia.org/wiki/Continuation_passing_style .. _`report about day one`: http://codespeak.net/pipermail/pypy-dev/2005q4/002510.html .. _`one about day two and three`: http://codespeak.net/pipermail/pypy-dev/2005q4/002512.html +.. _`the rest of the sprint`: http://codespeak.net/pipermail/pypy-dev/2005q4/002514.html PyPy release 0.7.0 =================== From arigo at codespeak.net Tue Oct 18 17:51:06 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 17:51:06 +0200 (CEST) Subject: [pypy-svn] r18740 - pypy/dist/pypy/translator/asm/ppcgen/test Message-ID: <20051018155106.415FC27B40@code1.codespeak.net> Author: arigo Date: Tue Oct 18 17:51:05 2005 New Revision: 18740 Modified: pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py Log: Ben Young's patch for Windows. Modified: pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py Tue Oct 18 17:51:05 2005 @@ -1,6 +1,5 @@ import autopath from pypy.translator.asm.ppcgen.ppc_assembler import b -import unittest import random import sys Modified: pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_func_builder.py Tue Oct 18 17:51:05 2005 @@ -1,5 +1,4 @@ -import unittest - +import py import random, sys, os from pypy.translator.asm.ppcgen.ppc_assembler import MyPPCAssembler @@ -10,7 +9,8 @@ class TestFuncBuilderTest(object): def setup_class(cls): - if os.uname()[-1] != 'Power Macintosh': + if (not hasattr(os, 'uname') or + os.uname()[-1] != 'Power Macintosh'): py.test.skip("can't test all of ppcgen on non-PPC!") def test_simple(self): Modified: pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_ppc.py Tue Oct 18 17:51:05 2005 @@ -1,3 +1,4 @@ +import py import random, sys, os from pypy.translator.asm.ppcgen.ppc_assembler import BasicPPCAssembler, MyPPCAssembler @@ -18,7 +19,8 @@ class TestAssemble(object): def setup_class(cls): - if os.uname()[-1] != 'Power Macintosh': + if (not hasattr(os, 'uname') or + os.uname()[-1] != 'Power Macintosh'): py.test.skip("can't test all of ppcgen on non-PPC!") def test_tuplelength(self): From arigo at codespeak.net Tue Oct 18 17:52:24 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 17:52:24 +0200 (CEST) Subject: [pypy-svn] r18741 - pypy/dist/pypy/translator/asm/ppcgen/test Message-ID: <20051018155224.B723D27B4B@code1.codespeak.net> Author: arigo Date: Tue Oct 18 17:52:23 2005 New Revision: 18741 Modified: pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py Log: Force PPC endianness for the test. Modified: pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/test/test_form.py Tue Oct 18 17:52:23 2005 @@ -25,7 +25,7 @@ def p(w): import struct - return struct.pack('i', w) + return struct.pack('>i', w) class TestForm(Form): From arigo at codespeak.net Tue Oct 18 18:07:24 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 18:07:24 +0200 (CEST) Subject: [pypy-svn] r18742 - in pypy/dist/pypy/module/stackless: . test Message-ID: <20051018160724.10E9627B4B@code1.codespeak.net> Author: arigo Date: Tue Oct 18 18:07:22 2005 New Revision: 18742 Added: pypy/dist/pypy/module/stackless/ (props changed) pypy/dist/pypy/module/stackless/__init__.py (contents, props changed) pypy/dist/pypy/module/stackless/cstack.py (contents, props changed) pypy/dist/pypy/module/stackless/test/ (props changed) pypy/dist/pypy/module/stackless/test/__init__.py - copied unchanged from r18741, pypy/dist/pypy/module/thread/test/__init__.py pypy/dist/pypy/module/stackless/test/test_cstack.py (contents, props changed) Log: Starting a 'stackless' app-level module. The name is tentative! For now it's only meant to expose to app-level bits of what C exposes to RPython-level. Added: pypy/dist/pypy/module/stackless/__init__.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/stackless/__init__.py Tue Oct 18 18:07:22 2005 @@ -0,0 +1,14 @@ + +# Package initialisation +from pypy.interpreter.mixedmodule import MixedModule + +class Module(MixedModule): + appleveldefs = { + } + + interpleveldefs = { + 'cstack_unwind': 'cstack.unwind', + 'cstack_frames_depth': 'cstack.frames_depth', + 'cstack_too_big': 'cstack.too_big', + 'cstack_check': 'cstack.check', + } Added: pypy/dist/pypy/module/stackless/cstack.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/stackless/cstack.py Tue Oct 18 18:07:22 2005 @@ -0,0 +1,18 @@ +from pypy.interpreter.gateway import ObjSpace +from pypy.rpython import objectmodel + +def unwind(): + objectmodel.stack_unwind() +unwind.unwrap_spec = [] + +def frames_depth(space): + return space.wrap(objectmodel.stack_frames_depth()) +frames_depth.unwrap_spec = [ObjSpace] + +def too_big(space): + return space.wrap(objectmodel.stack_too_big()) +too_big.unwrap_spec = [ObjSpace] + +def check(): + objectmodel.stack_check() +check.unwrap_spec = [] Added: pypy/dist/pypy/module/stackless/test/test_cstack.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/stackless/test/test_cstack.py Tue Oct 18 18:07:22 2005 @@ -0,0 +1,26 @@ +from pypy.conftest import gettestobjspace + + +class AppTestCStack: + + def setup_class(cls): + space = gettestobjspace(usemodules=('stackless',)) + cls.space = space + + def test_dummy(self): + # dummy tests, mostly just testing that they don't crash + import stackless + stackless.cstack_unwind() + assert not stackless.cstack_too_big() + stackless.cstack_check() + + def test_frames_depth(self): + import stackless + def f(n): + if n == 0: + return [] + lst = f(n-1) + lst.append(stackless.cstack_frames_depth()) + return lst + lst = f(5) + assert lst[0] > lst[1] > lst[2] > lst[3] > lst[4] > 0 From arigo at codespeak.net Tue Oct 18 18:18:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 18:18:29 +0200 (CEST) Subject: [pypy-svn] r18743 - pypy/dist/pypy/module/stackless Message-ID: <20051018161829.F12F327B40@code1.codespeak.net> Author: arigo Date: Tue Oct 18 18:18:29 2005 New Revision: 18743 Modified: pypy/dist/pypy/module/stackless/cstack.py Log: detail Modified: pypy/dist/pypy/module/stackless/cstack.py ============================================================================== --- pypy/dist/pypy/module/stackless/cstack.py (original) +++ pypy/dist/pypy/module/stackless/cstack.py Tue Oct 18 18:18:29 2005 @@ -10,7 +10,7 @@ frames_depth.unwrap_spec = [ObjSpace] def too_big(space): - return space.wrap(objectmodel.stack_too_big()) + return space.newbool(objectmodel.stack_too_big()) too_big.unwrap_spec = [ObjSpace] def check(): From pedronis at codespeak.net Tue Oct 18 22:37:07 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 18 Oct 2005 22:37:07 +0200 (CEST) Subject: [pypy-svn] r18744 - pypy/dist/pypy/objspace/flow/test Message-ID: <20051018203707.E6C0627B44@code1.codespeak.net> Author: pedronis Date: Tue Oct 18 22:37:06 2005 New Revision: 18744 Modified: pypy/dist/pypy/objspace/flow/test/test_model.py Log: changing test making nowadays wrong assumptions. Modified: pypy/dist/pypy/objspace/flow/test/test_model.py ============================================================================== --- pypy/dist/pypy/objspace/flow/test/test_model.py (original) +++ pypy/dist/pypy/objspace/flow/test/test_model.py Tue Oct 18 22:37:06 2005 @@ -117,12 +117,14 @@ v = Variable() assert v.name[0] == 'v' and v.name[1:].isdigit() assert not v.renamed - num = int(v.name[1:]) v.rename("foobar") - assert v.name == "foobar_%d" % num + name1 = v.name + assert name1.startswith('foobar_') + assert name1.split('_', 1)[1].isdigit() assert v.renamed v.rename("not again") - assert v.name == "foobar_%d" % num + assert v.name == name1 v2 = Variable(v) assert v2.renamed assert v2.name.startswith("foobar_") and v2.name != v.name + assert v2.name.split('_', 1)[1].isdigit() From arigo at codespeak.net Tue Oct 18 23:03:17 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 18 Oct 2005 23:03:17 +0200 (CEST) Subject: [pypy-svn] r18745 - pypy/dist/pypy/doc Message-ID: <20051018210317.2E28227B58@code1.codespeak.net> Author: arigo Date: Tue Oct 18 23:03:16 2005 New Revision: 18745 Modified: pypy/dist/pypy/doc/coding-guide.txt Log: Precised the RPython rules for the usage of indices in lists. Half of these rules could be lifted for clarity at the expense of a very small slow-down to check them at run-time. The other half are limitations of the RTyper, which could also be removed. The risk in the latter case is that user code would silently start using the slower version instead of failing to translate, even when a small effort from the programmer would be enough to convince the Annotator/RTyper that the fast version works as well. Modified: pypy/dist/pypy/doc/coding-guide.txt ============================================================================== --- pypy/dist/pypy/doc/coding-guide.txt (original) +++ pypy/dist/pypy/doc/coding-guide.txt Tue Oct 18 23:03:16 2005 @@ -149,22 +149,26 @@ **lists** - lists are used as an allocated array; list.append() does naive resizing, so as - far as possible use list comprehensions (see below). list.extend() or the += - operator are allowed and efficient. - Repetition via `*` or `*=` is fully supported as well. + lists are used as an allocated array. Lists are over-allocated, so list.append() + is reasonably fast. Negative or out-of-bound indexes are only allowed for the + most common operations, as follows: - - *indexing* - negative indexes are disallowed. Indexes are checked when requested + - *indexing*: + positive and negative indexes are allowed. Indexes are checked when requested by an IndexError exception clause. - - *slicing* - the slice start must be within bounds. The stop doesn't need to. - Negative indexes are disallowed, except for the [:-1] special case. - - - *insert* - the index must be withing bounds (not checked) and must not be negative - (checked at compile-time). + - *slicing*: + the slice start must be within bounds. The stop doesn't need to, but it must + not be smaller than the start. All negative indexes are disallowed, except for + the [:-1] special case. No step. + + - *other operators*: + ``+``, ``+=``, ``in``, ``*``, ``*=``, ``==``, ``!=`` work as expected. + + - *methods*: + append, index, insert, extend, reverse, pop. The index used in pop() follows + the same rules as for *indexing* above. The index used in insert() must be within + bounds and not negative. **dicts** From mwh at codespeak.net Tue Oct 18 23:10:46 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 18 Oct 2005 23:10:46 +0200 (CEST) Subject: [pypy-svn] r18746 - pypy/dist/pypy/translator/asm Message-ID: <20051018211046.708B727B58@code1.codespeak.net> Author: mwh Date: Tue Oct 18 23:10:45 2005 New Revision: 18746 Modified: pypy/dist/pypy/translator/asm/genasm.py Log: comment now-unnecessary stuff out Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 18 23:10:45 2005 @@ -4,34 +4,34 @@ from pypy.rpython.lltype import Signed from pypy.translator.asm.simulator import Machine, TranslateProgram -#Available Machine code targets (processor+operating system) -TARGET_UNKNOWN=0 -TARGET_PPC=1 -TARGET_WIN386=2 - -#set one of these -ASM_TARGET=TARGET_UNKNOWN -#ASM_TARGET=TARGET_WIN386 - -def determine_target(): - global ASM_TARGET - if sys.platform == 'darwin': - if os.uname()[-1] == 'Power Macintosh': - ASM_TARGET = TARGET_PPC - elif sys.platform == 'win32': - if 'Intel' in sys.version: - ASM_TARGET = TARGET_WIN386 - -determine_target() -if ASM_TARGET == TARGET_UNKNOWN: - raise Exception, 'Unknown Machine-code target specified.' - -if ASM_TARGET==TARGET_PPC: - from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler - from pypy.translator.asm.ppcgen.func_builder import make_func -elif ASM_TARGET==TARGET_WIN386: - from pypy.translator.asm.i386gen.i386_assembler import i386Assembler as PPCAssembler #spoof system for time being - from pypy.translator.asm.i386gen.i386_assembler import make_func +# #Available Machine code targets (processor+operating system) +# TARGET_UNKNOWN=0 +# TARGET_PPC=1 +# TARGET_WIN386=2 + +# #set one of these +# ASM_TARGET=TARGET_UNKNOWN +# #ASM_TARGET=TARGET_WIN386 + +# def determine_target(): +# global ASM_TARGET +# if sys.platform == 'darwin': +# if os.uname()[-1] == 'Power Macintosh': +# ASM_TARGET = TARGET_PPC +# elif sys.platform == 'win32': +# if 'Intel' in sys.version: +# ASM_TARGET = TARGET_WIN386 + +# determine_target() +# if ASM_TARGET == TARGET_UNKNOWN: +# raise Exception, 'Unknown Machine-code target specified.' + +# if ASM_TARGET==TARGET_PPC: +# from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler +# from pypy.translator.asm.ppcgen.func_builder import make_func +# elif ASM_TARGET==TARGET_WIN386: +# from pypy.translator.asm.i386gen.i386_assembler import i386Assembler as PPCAssembler #spoof system for time being +# from pypy.translator.asm.i386gen.i386_assembler import make_func def genasm(translator, processor): From arigo at codespeak.net Wed Oct 19 14:02:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 14:02:46 +0200 (CEST) Subject: [pypy-svn] r18748 - pypy/extradoc/sprintinfo/paris Message-ID: <20051019120246.B128027B5A@code1.codespeak.net> Author: arigo Date: Wed Oct 19 14:02:45 2005 New Revision: 18748 Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Log: Clarifications following pypy-dev mails (thanks Christian). Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/stackless-discussion.txt (original) +++ pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Wed Oct 19 14:02:45 2005 @@ -98,7 +98,8 @@ function's state to be captured in a new ``continuation`` object that is returned to the parent. Only one frame, the current one, is captured this way. The current frame is suspended and the caller - continues to run. + continues to run. Note that the caller is only resumed once: when + ``yield_continuation()`` is called. See below. * A ``continuation`` object can be jumped to by calling its ``switch()`` method with no argument. @@ -108,16 +109,13 @@ the source ``switch()`` that was just executed, or None in the case described below. -* ``yield_continuation()`` only works when called from a function whose - return type is precisely ``continuation``. In other words this - function must also contain a regular return statement that returns a - ``continuation``. When the captured continuation is later resumed and - the function eventually returns via this regular return statement, - then the returned ``continuation`` object designates the place where - execution should switch to (i.e. execution does not return to the - original caller). In such an implicit switch, a None is returned to - the ``switch()`` or ``yield_continuation()`` at place that we switch - to. +* the function that called ``yield_continuation()`` also has a normal + return statement, like all functions. This statement must return + another ``continuation`` object. The latter is *not* returned to the + original caller; there is no way to return several times to the + caller. Instead, it designates the place to which the execution must + jump, as if by a ``switch()``. The place to which we jump this way + will see a None as the source continuation. * every continuation must be resumed once and only once. Not resuming it at all causes a leak. Resuming it several times causes a crash. From arigo at codespeak.net Wed Oct 19 14:11:48 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 14:11:48 +0200 (CEST) Subject: [pypy-svn] r18749 - pypy/dist/pypy/annotation Message-ID: <20051019121148.5AD5427B61@code1.codespeak.net> Author: arigo Date: Wed Oct 19 14:11:47 2005 New Revision: 18749 Modified: pypy/dist/pypy/annotation/unaryop.py Log: Forgot to check this in with rev 18733. Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Wed Oct 19 14:11:47 2005 @@ -609,6 +609,9 @@ setattr(r.ootype._example(), s_attr.const, v._example()) + def is_true(p): + return SomeBool() + class __extend__(SomeOOBoundMeth): def simple_call(m, *args_s): llargs = [annotation_to_lltype(arg_s)._example() for arg_s in args_s] From arigo at codespeak.net Wed Oct 19 14:29:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 14:29:14 +0200 (CEST) Subject: [pypy-svn] r18750 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051019122914.36D0A27B61@code1.codespeak.net> Author: arigo Date: Wed Oct 19 14:29:12 2005 New Revision: 18750 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Log: ootype, rclass and llinterp support for comparing instances (always by identity). Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 19 14:29:12 2005 @@ -656,6 +656,11 @@ assert isinstance(inst, ootype._instance) return bool(inst) + def op_oois(self, inst1, inst2): + assert isinstance(inst1, ootype._instance) + assert isinstance(inst2, ootype._instance) + return inst1 == inst2 # NB. differently-typed NULLs must be equal + def op_instanceof(self, inst, INST): return ootype.instanceof(inst, INST) Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Oct 19 14:29:12 2005 @@ -171,6 +171,14 @@ def __nonzero__(self): return True # better be explicit -- overridden in _null_instance + def __eq__(self, other): + if not isinstance(other, _instance): + raise TypeError("comparing an _instance with %r" % (other,)) + return self is other # same comment as __nonzero__ + + def __ne__(self, other): + return not (self == other) + class _null_instance(_instance): def __init__(self, INSTANCE): @@ -192,6 +200,11 @@ def __nonzero__(self): return False + def __eq__(self, other): + if not isinstance(other, _instance): + raise TypeError("comparing an _instance with %r" % (other,)) + return not other + class _callable(object): def __init__(self, TYPE, **attrs): Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 14:29:12 2005 @@ -262,3 +262,14 @@ return v else: return NotImplemented + + def rtype_is_((r_ins1, r_ins2), hop): + # NB. this version performs no cast to the common base class + vlist = hop.inputargs(r_ins1, r_ins2) + return hop.genop('oois', vlist, resulttype=ootype.Bool) + + rtype_eq = rtype_is_ + + def rtype_ne(rpair, hop): + v = rpair.rtype_eq(hop) + return hop.genop("bool_not", [v], resulttype=ootype.Bool) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 14:29:12 2005 @@ -238,3 +238,16 @@ assert res == 111 res = interpret(f, [0], type_system='ootype') assert res == 0 + +def test_instance_comparison(): + def f(flag): + a = Subclass() + if flag: + b = a + else: + b = EmptyBase() + return (a is b)*100 + (a == b)*10 + (a != b) + res = interpret(f, [True], type_system='ootype') + assert res == 110 + res = interpret(f, [False], type_system='ootype') + assert res == 1 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Wed Oct 19 14:29:12 2005 @@ -248,3 +248,28 @@ assert commonBaseclass(E, B) is None assert commonBaseclass(F, A) is None +def test_equality(): + A = Instance("A", None) + B = Instance("B", A) + a1 = new(A) + a2 = new(A) + b1 = new(B) + az = null(A) + bz = null(B) + assert a1 + assert a2 + assert not az + assert not bz + result = [] + for first in [a1, a2, b1, az, bz]: + for second in [a1, a2, b1, az, bz]: + eq = first == second + assert (first != second) == (not eq) + result.append(eq) + assert result == [ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 1, + 0, 0, 0, 1, 1, + ] From pedronis at codespeak.net Wed Oct 19 14:49:36 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 19 Oct 2005 14:49:36 +0200 (CEST) Subject: [pypy-svn] r18751 - pypy/dist/pypy/translator/tool Message-ID: <20051019124936.7E14727B57@code1.codespeak.net> Author: pedronis Date: Wed Oct 19 14:49:34 2005 New Revision: 18751 Modified: pypy/dist/pypy/translator/tool/cbuild.py Log: specify -O2 for standalone on darwin too Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Wed Oct 19 14:49:34 2005 @@ -258,17 +258,22 @@ libraries=[], library_dirs=None): from distutils.ccompiler import new_compiler ext = '' - extra_preargs = None + compile_extra = [] + link_extra = [] + if not include_dirs: include_dirs = [] if not library_dirs: library_dirs = [] - if not sys.platform in ('win32', 'darwin'): + if not sys.platform in ('win32', 'darwin'): # xxx libraries.append('m') libraries.append('pthread') - extra_preargs = ['-O2', '-pthread'] # XXX 2 x hackish + compile_extra += ['-O2', '-pthread'] + link_extra += ['-pthread'] if sys.platform == 'darwin': include_dirs.append('/sw/include') + compile_extra += ['-O2'] + if outputfilename is None: outputfilename = py.path.local(cfilenames[0]).new(ext=ext) else: @@ -286,7 +291,7 @@ try: res = compiler.compile([cfile.basename], include_dirs=include_dirs, - extra_preargs=extra_preargs) + extra_preargs=compile_extra) assert len(res) == 1 cobjfile = py.path.local(res[0]) assert cobjfile.check() @@ -295,8 +300,8 @@ old.chdir() compiler.link_executable(objects, str(outputfilename), libraries=libraries, - extra_preargs=extra_preargs, - library_dirs=library_dirs) + extra_preargs=link_extra, + library_dirs=library_dirs) return str(outputfilename) def check_boehm_presence(): From arigo at codespeak.net Wed Oct 19 15:05:41 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 15:05:41 +0200 (CEST) Subject: [pypy-svn] r18752 - in pypy/dist/pypy/translator: c/src llvm llvm/module llvm/test Message-ID: <20051019130541.E8B9627B5B@code1.codespeak.net> Author: arigo Date: Wed Oct 19 15:05:40 2005 New Revision: 18752 Modified: pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/src/stack.h pypy/dist/pypy/translator/llvm/externs2ll.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/module/genexterns.c pypy/dist/pypy/translator/llvm/module/support.py pypy/dist/pypy/translator/llvm/test/test_typed.py Log: trying to fix llvm failures introduced during the sprint: * '%' between floats was removed, so remove it from the test * LL_stack_too_big() and LL_stack_unwind() calls are introduced when there are recursive calls. Solved by including stack.h in the compiled ccode.c. * Added the RuntimeError exception for LL_stack_unwind(). 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 Wed Oct 19 15:05:40 2005 @@ -47,7 +47,7 @@ RPySTAT_RESULT* LL_os_stat(RPyString * fname); RPySTAT_RESULT* LL_os_fstat(long fd); long LL_os_lseek(long fd, long pos, long how); -long LL_os_isatty(long fd); +int LL_os_isatty(long fd); RPyString *LL_os_strerror(int errnum); long LL_os_system(RPyString * fname); void LL_os_unlink(RPyString * fname); @@ -165,8 +165,8 @@ return res; } -long LL_os_isatty(long fd) { - return (int)isatty((int)fd); +int LL_os_isatty(long fd) { + return isatty((int)fd); } #ifdef HAVE_FTRUNCATE Modified: pypy/dist/pypy/translator/c/src/stack.h ============================================================================== --- pypy/dist/pypy/translator/c/src/stack.h (original) +++ pypy/dist/pypy/translator/c/src/stack.h Wed Oct 19 15:05:40 2005 @@ -6,7 +6,8 @@ # define MAX_STACK_SIZE (1 << 19) #endif -char LL_stack_too_big(void); +void LL_stack_unwind(void); +int LL_stack_too_big(void); #ifndef PYPY_NOT_MAIN_FILE @@ -19,7 +20,7 @@ #endif } -char LL_stack_too_big(void) +int LL_stack_too_big(void) { char local; long result; Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Wed Oct 19 15:05:40 2005 @@ -84,6 +84,11 @@ %b = cast int %t to bool ret bool %b } +internal fastcc bool %LL_stack_too_big() { + %t = call fastcc int %LL_stack_too_big() + %b = cast int %t to bool + ret bool %b +} """ return decl, impl @@ -141,7 +146,7 @@ include_files.append(j(j(os.path.dirname(__file__), "module"), "genexterns.c")) from pypy.translator.c import extfunc - for f in ["ll_os", "ll_math", "ll_time", "ll_strtod"]: + for f in ["ll_os", "ll_math", "ll_time", "ll_strtod", "stack"]: include_files.append(j(j(os.path.dirname(extfunc.__file__), "src"), f + ".h")) for f in include_files: Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Wed Oct 19 15:05:40 2005 @@ -132,6 +132,7 @@ support_functions = "%raisePyExc_IOError %raisePyExc_ValueError "\ "%raisePyExc_OverflowError %raisePyExc_ZeroDivisionError "\ + "%raisePyExc_RuntimeError "\ "%prepare_ZeroDivisionError %prepare_OverflowError %prepare_ValueError "\ "%RPyString_FromString %RPyString_AsString %RPyString_Size".split() Modified: pypy/dist/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm/module/genexterns.c Wed Oct 19 15:05:40 2005 @@ -8,6 +8,7 @@ void raisePyExc_ValueError(char *); void raisePyExc_OverflowError(char *); void raisePyExc_ZeroDivisionError(char *); +void raisePyExc_RuntimeError(char *); #define RPyRaiseSimpleException(exctype, errormsg) raise##exctype(errormsg) // Generated by rpython - argggh have to feed in prototypes Modified: pypy/dist/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm/module/support.py (original) +++ pypy/dist/pypy/translator/llvm/module/support.py Wed Oct 19 15:05:40 2005 @@ -89,7 +89,7 @@ #prepare and raise exceptions (%msg not used right now!) -for exc in "IOError ZeroDivisionError OverflowError ValueError".split(): #_ZER _OVF _VAL +for exc in "IOError ZeroDivisionError OverflowError ValueError RuntimeError".split(): #_ZER _OVF _VAL extfunctions["%%raisePyExc_%(exc)s" % locals()] = ((), """ internal fastcc void %%raisePyExc_%(exc)s(sbyte* %%msg) { %%exception_value = cast %%structtype.%(exc)s* %%structinstance.%(exc)s to %%RPYTHON_EXCEPTION* Modified: pypy/dist/pypy/translator/llvm/test/test_typed.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_typed.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_typed.py Wed Oct 19 15:05:40 2005 @@ -211,9 +211,10 @@ def test_float_operations(): #llvm rem operation working starting llvm1.6") #see: http://llvm.cs.uiuc.edu/bugs/show_bug.cgi?id=611 + import math def func(x, y): z = x + y / 2.1 * x - z = z % 60.0 + z = math.fmod(z, 60.0) z = pow(z, 2) z = -z return int(z) From arigo at codespeak.net Wed Oct 19 17:03:38 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 17:03:38 +0200 (CEST) Subject: [pypy-svn] r18755 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051019150338.DA25A27B5A@code1.codespeak.net> Author: arigo Date: Wed Oct 19 17:03:38 2005 New Revision: 18755 Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: fix bug with methods and class attributes not being found if present in a superclass but used from a subclass. Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 17:03:38 2005 @@ -1,5 +1,5 @@ import types -from pypy.rpython.rmodel import inputconst +from pypy.rpython.rmodel import inputconst, TyperError from pypy.rpython.rclass import AbstractClassRepr, AbstractInstanceRepr, \ getinstancerepr, getclassrepr, get_type_repr from pypy.rpython.rpbc import getsignature @@ -95,11 +95,24 @@ for name, attrdef in attrs: if not attrdef.readonly: continue - try: - impl = self.classdef.cls.__dict__[name] - except KeyError: - continue mangled = mangle(name) + if mangled in allmethods or mangled in allclassattributes: + # if the method/attr was already found in a parent class, + # we register it again only if it is overridden. + if name not in self.classdef.cls.__dict__: + continue + impl = self.classdef.cls.__dict__[name] + else: + # otherwise, for new method/attrs, we look in all parent + # classes to see if it's defined in a parent but only + # actually first used in self.classdef. + for clsdef in self.classdef.getmro(): + if name in clsdef.cls.__dict__: + impl = clsdef.cls.__dict__[name] + break + else: + raise TyperError("class %r has no attribute %r" % ( + self.classdef.cls, name)) if classrepr.prepare_method(attrdef.s_value) is not None: # a regular method f, inputs, ret = getsignature(self.rtyper, impl) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 17:03:38 2005 @@ -118,6 +118,18 @@ result = interpret(dummyfn, [False], type_system='ootype') assert result == 2 +def test_method_used_in_subclasses_only(): + class A: + def meth(self): + return 123 + class B(A): + pass + def f(): + x = B() + return x.meth() + res = interpret(f, [], type_system='ootype') + assert res == 123 + class HasAField(object): def f(self): return self.a @@ -189,6 +201,26 @@ res = interpret(dummyfn, [], type_system='ootype') assert res == 4 +def test_classattr_used_in_subclasses_only(): + class Subclass1(HasClassAttr): + pass + class Subclass2(HasClassAttr): + pass + class SubSubclass2(Subclass2): + a = 5432 + def dummyfn(flag): + inst1 = Subclass1() + inst1.a += 42 # used as default + if flag: + inst2 = Subclass2() + else: + inst2 = SubSubclass2() + return inst1.a + inst2.a + res = interpret(dummyfn, [True], type_system='ootype') + assert res == (3 + 42) + 3 + res = interpret(dummyfn, [False], type_system='ootype') + assert res == (3 + 42) + 5432 + def test_name_clashes(): class NameClash1(object): def _TYPE(self): From arigo at codespeak.net Wed Oct 19 17:12:41 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 17:12:41 +0200 (CEST) Subject: [pypy-svn] r18757 - pypy/dist/pypy/rpython/ootypesystem/test Message-ID: <20051019151241.6CEE627B5A@code1.codespeak.net> Author: arigo Date: Wed Oct 19 17:12:40 2005 New Revision: 18757 Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: More tests from the lltype's rclass that pass on ootype. Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 17:12:40 2005 @@ -130,6 +130,19 @@ res = interpret(f, [], type_system='ootype') assert res == 123 +def test_method_both_A_and_B(): + class A: + def meth(self): + return 123 + class B(A): + pass + def f(): + a = A() + b = B() + return a.meth() + b.meth() + res = interpret(f, [], type_system='ootype') + assert res == 246 + class HasAField(object): def f(self): return self.a @@ -283,3 +296,107 @@ assert res == 110 res = interpret(f, [False], type_system='ootype') assert res == 1 + +def test_is(): + class A: 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)) + res = interpret(f, [0], type_system='ootype') + assert res == 0x0004 + res = interpret(f, [1], type_system='ootype') + assert res == 0x0020 + res = interpret(f, [2], type_system='ootype') + assert res == 0x0100 + res = interpret(f, [3], type_system='ootype') + assert res == 0x0200 + +def test_eq(): + class A: 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 == b) | 0x0002*(a == c) | 0x0004*(a == d) | + 0x0008*(a == e) | 0x0010*(b == c) | 0x0020*(b == d) | + 0x0040*(b == e) | 0x0080*(c == d) | 0x0100*(c == e) | + 0x0200*(d == e)) + res = interpret(f, [0], type_system='ootype') + assert res == 0x0004 + res = interpret(f, [1], type_system='ootype') + assert res == 0x0020 + res = interpret(f, [2], type_system='ootype') + assert res == 0x0100 + res = interpret(f, [3], type_system='ootype') + assert res == 0x0200 + +def test_istrue(): + class A: + pass + def f(i): + if i == 0: + a = A() + else: + a = None + if a: + return 1 + else: + return 2 + res = interpret(f, [0], type_system='ootype') + assert res == 1 + res = interpret(f, [1], type_system='ootype') + assert res == 2 + +def test_ne(): + class A: 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 != b) | 0x0002*(a != c) | 0x0004*(a != d) | + 0x0008*(a != e) | 0x0010*(b != c) | 0x0020*(b != d) | + 0x0040*(b != e) | 0x0080*(c != d) | 0x0100*(c != e) | + 0x0200*(d != e)) + res = interpret(f, [0], type_system='ootype') + assert res == ~0x0004 & 0x3ff + res = interpret(f, [1], type_system='ootype') + assert res == ~0x0020 & 0x3ff + res = interpret(f, [2], type_system='ootype') + assert res == ~0x0100 & 0x3ff + res = interpret(f, [3], type_system='ootype') + assert res == ~0x0200 & 0x3ff From arigo at codespeak.net Wed Oct 19 17:26:05 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 17:26:05 +0200 (CEST) Subject: [pypy-svn] r18758 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051019152605.8999A27B5A@code1.codespeak.net> Author: arigo Date: Wed Oct 19 17:26:04 2005 New Revision: 18758 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Log: ootype: type() and issubtype() operations. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 19 17:26:04 2005 @@ -664,6 +664,12 @@ def op_instanceof(self, inst, INST): return ootype.instanceof(inst, INST) + def op_classof(self, inst): + return ootype.classof(inst) + + def op_subclassof(self, class1, class2): + return ootype.subclassof(class1, class2) + # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help # for failing tests Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Oct 19 17:26:04 2005 @@ -275,8 +275,14 @@ return bool(inst) and isSubclass(inst._TYPE, INSTANCE) def classof(inst): + assert isinstance(inst, _instance) return runtimeClass(inst._TYPE) +def subclassof(class1, class2): + assert isinstance(class1, _class) + assert isinstance(class2, _class) + return isSubclass(class1._INSTANCE, class2._INSTANCE) + def addFields(INSTANCE, fields): INSTANCE._add_fields(fields) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 17:26:04 2005 @@ -32,6 +32,11 @@ # return getinstancerepr(self.rtyper, subclassdef).lowleveltype._class + def rtype_issubtype(self, hop): + class_repr = get_type_repr(self.rtyper) + vlist = hop.inputargs(class_repr, class_repr) + return hop.genop('subclassof', vlist, resulttype=ootype.Bool) + def mangle(name): # XXX temporary: for now it looks like a good idea to mangle names @@ -201,6 +206,10 @@ vinst, = hop.inputargs(self) return hop.genop('oononnull', [vinst], resulttype=ootype.Bool) + def rtype_type(self, hop): + vinst, = hop.inputargs(self) + return hop.genop('classof', [vinst], resulttype=ootype.Class) + def convert_const(self, value): if value is None: return ootype.null(self.lowleveltype) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 17:26:04 2005 @@ -284,6 +284,33 @@ res = interpret(f, [0], type_system='ootype') assert res == 0 +def test_issubclass_type(): + class A: + pass + class B(A): + pass + def f(i): + if i == 0: + c1 = A() + else: + c1 = B() + return issubclass(type(c1), B) + res = interpret(f, [0], type_system='ootype') + assert res is False + res = interpret(f, [1], type_system='ootype') + assert res is True + + def g(i): + if i == 0: + c1 = A() + else: + c1 = B() + return issubclass(type(c1), A) + res = interpret(g, [0], type_system='ootype') + assert res is True + res = interpret(g, [1], type_system='ootype') + assert res is True + def test_instance_comparison(): def f(flag): a = Subclass() Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Wed Oct 19 17:26:04 2005 @@ -273,3 +273,18 @@ 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, ] + +def test_subclassof(): + A = Instance("A", None) + B = Instance("B", A) + C = Instance("C", B) + result = [] + for first in [A, B, C]: + for second in [A, B, C]: + result.append(subclassof(runtimeClass(first), + runtimeClass(second))) + assert result == [ + 1, 0, 0, + 1, 1, 0, + 1, 1, 1, + ] From mwh at codespeak.net Wed Oct 19 17:35:12 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 19 Oct 2005 17:35:12 +0200 (CEST) Subject: [pypy-svn] r18759 - pypy/dist/pypy/rpython/test Message-ID: <20051019153512.68B1C27B5B@code1.codespeak.net> Author: mwh Date: Wed Oct 19 17:35:11 2005 New Revision: 18759 Modified: pypy/dist/pypy/rpython/test/test_llinterp.py Log: small reformatting 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 Wed Oct 19 17:35:11 2005 @@ -72,8 +72,7 @@ else: return lltype_to_annotation(T) - t, typer = gengraph(func, [annotation(x) - for x in values], + t, typer = gengraph(func, [annotation(x) for x in values], viewbefore, policy, type_system=type_system) interp = LLInterpreter(t.flowgraphs, typer) _tcache[key] = (t, interp) From pedronis at codespeak.net Wed Oct 19 17:38:08 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 19 Oct 2005 17:38:08 +0200 (CEST) Subject: [pypy-svn] r18760 - in pypy/dist/pypy: annotation rpython Message-ID: <20051019153808.B45A827B5B@code1.codespeak.net> Author: pedronis Date: Wed Oct 19 17:38:03 2005 New Revision: 18760 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/listdef.py pypy/dist/pypy/annotation/unaryop.py pypy/dist/pypy/rpython/rlist.py Log: preparatory changes for allowing separate support for fixed-size lists. addition and extend for lists and equality should not unify eagerly anymore trashing mutated/resized flags: use (possibly circular) chains of read_item and generalize instead. Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Wed Oct 19 17:38:03 2005 @@ -349,10 +349,11 @@ def union((lst1, lst2)): return SomeList(lst1.listdef.union(lst2.listdef)) - add = union + def add((lst1, lst2)): + return lst1.listdef.offspring(lst2.listdef) def eq((lst1, lst2)): - lst1.listdef.union(lst2.listdef) + lst1.listdef.agree(lst2.listdef) return SomeBool() ne = eq Modified: pypy/dist/pypy/annotation/listdef.py ============================================================================== --- pypy/dist/pypy/annotation/listdef.py (original) +++ pypy/dist/pypy/annotation/listdef.py Wed Oct 19 17:38:03 2005 @@ -99,6 +99,21 @@ self.listitem.merge(other.listitem) return self + def agree(self, other): + s_self_value = self.read_item() + s_other_value = other.read_item() + self.generalize(s_other_value) + other.generalize(s_self_value) + + def offspring(self, other): + s_self_value = self.read_item() + s_other_value = other.read_item() + s_newlst = self.bookkeeper.newlist(s_self_value, s_other_value) + s_newvalue = s_newlst.listdef.read_item() + self.generalize(s_newvalue) + other.generalize(s_newvalue) + return s_newlst + def generalize(self, s_value): self.listitem.generalize(s_value) Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Wed Oct 19 17:38:03 2005 @@ -256,7 +256,7 @@ def method_extend(lst, s_iterable): lst.listdef.resize() if isinstance(s_iterable, SomeList): # unify the two lists - lst.listdef.union(s_iterable.listdef) + lst.listdef.agree(s_iterable.listdef) else: s_iter = s_iterable.iter() self.method_append(s_iter.next()) Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Wed Oct 19 17:38:03 2005 @@ -289,7 +289,8 @@ if r_lst1.listitem is None or r_lst2.listitem is None: return NotImplemented if r_lst1.listitem is not r_lst2.listitem: - return NotImplemented + if r_lst1.lowleveltype != r_lst2.lowleveltype: + return NotImplemented return v def rtype_add((self, _), hop): From arigo at codespeak.net Wed Oct 19 17:45:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 17:45:43 +0200 (CEST) Subject: [pypy-svn] r18761 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051019154543.3461127B5B@code1.codespeak.net> Author: arigo Date: Wed Oct 19 17:45:42 2005 New Revision: 18761 Added: pypy/dist/pypy/rpython/ootypesystem/test/test_oopbc.py Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: Two tests that pass with a minor fix. Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 17:45:42 2005 @@ -185,8 +185,7 @@ elif mangled in self.allclassattributes: # class attributes if hop.s_result.is_constant(): - oovalue = hop.r_result.convert_const(hop.s_result.const) - return hop.inputconst(hop.r_result, oovalue) + return hop.inputconst(hop.r_result, hop.s_result.const) else: cname = hop.inputconst(ootype.Void, mangled) return hop.genop("oosend", [cname, v_inst], Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 17:45:42 2005 @@ -311,6 +311,15 @@ res = interpret(g, [1], type_system='ootype') assert res is True +def test_staticmethod(): + class A(object): + f = staticmethod(lambda x, y: x*y) + def f(): + a = A() + return a.f(6, 7) + res = interpret(f, [], type_system='ootype') + assert res == 42 + def test_instance_comparison(): def f(flag): a = Subclass() Added: pypy/dist/pypy/rpython/ootypesystem/test/test_oopbc.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oopbc.py Wed Oct 19 17:45:42 2005 @@ -0,0 +1,19 @@ +from pypy.rpython.ootypesystem import ootype +from pypy.rpython.test.test_llinterp import interpret +import py + +def test_function_pointer(): + def g1(): + return 111 + def g2(): + return 222 + def f(flag): + if flag: + g = g1 + else: + g = g2 + return g() - 1 + res = interpret(f, [True], type_system='ootype') + assert res == 110 + res = interpret(f, [False], type_system='ootype') + assert res == 221 From arigo at codespeak.net Wed Oct 19 18:27:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 18:27:23 +0200 (CEST) Subject: [pypy-svn] r18762 - in pypy/dist/pypy: annotation rpython rpython/ootypesystem rpython/ootypesystem/test Message-ID: <20051019162723.D127E27B5E@code1.codespeak.net> Author: arigo Date: Wed Oct 19 18:27:22 2005 New Revision: 18762 Modified: pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rtyper.py Log: ootyper: * hash(instances), with a new built-in ootype.ooidentityhash() supported by the annotator and producing an operation with the same name. * moved some ootype-specific code from rbuiltin.py to ootypesystem/rbuiltin.py * quick fix in gendirectcall() that enables it to work in simple cases Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Wed Oct 19 18:27:22 2005 @@ -393,11 +393,16 @@ assert isinstance(c, SomeOOClass) return SomeOOInstance(c.ootype) +def ooidentityhash(i): + assert isinstance(i, SomeOOInstance) + return SomeInteger() + BUILTIN_ANALYZERS[ootype.instanceof] = instanceof BUILTIN_ANALYZERS[ootype.new] = new BUILTIN_ANALYZERS[ootype.null] = null BUILTIN_ANALYZERS[ootype.runtimenew] = runtimenew BUILTIN_ANALYZERS[ootype.classof] = classof +BUILTIN_ANALYZERS[ootype.ooidentityhash] = ooidentityhash #________________________________ # non-gc objects Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 19 18:27:22 2005 @@ -670,6 +670,9 @@ def op_subclassof(self, class1, class2): return ootype.subclassof(class1, class2) + def op_ooidentityhash(self, inst): + return ootype.ooidentityhash(inst) + # by default we route all logging messages to nothingness # e.g. tests can then switch on logging to get more help # for failing tests Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Oct 19 18:27:22 2005 @@ -324,4 +324,10 @@ def oodowncast(INSTANCE, instance): assert instanceof(instance, INSTANCE) return instance - + +def ooidentityhash(inst): + assert isinstance(inst, _instance) + if inst: + return id(inst) + else: + return 0 # for all null instances Modified: pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rbuiltin.py Wed Oct 19 18:27:22 2005 @@ -1,11 +1,33 @@ +from pypy.annotation import model as annmodel from pypy.rpython.ootypesystem import ootype from pypy.rpython.ootypesystem import rclass from pypy.objspace.flow.model import Constant +def rtype_new(hop): + assert hop.args_s[0].is_constant() + vlist = hop.inputargs(ootype.Void) + return hop.genop('new', vlist, + resulttype = hop.r_result.lowleveltype) + +def rtype_classof(hop): + assert isinstance(hop.args_s[0], annmodel.SomeOOInstance) + return hop.genop('classof', hop.args_v, + resulttype = ootype.Class) + +def rtype_runtimenew(hop): + assert isinstance(hop.args_s[0], annmodel.SomeOOClass) + return hop.genop('runtimenew', hop.args_v, + resulttype = hop.r_result.lowleveltype) + +def rtype_ooidentityhash(hop): + assert isinstance(hop.args_s[0], annmodel.SomeOOInstance) + return hop.genop('ooidentityhash', hop.args_v, + resulttype = ootype.Signed) + def rtype_builtin_isinstance(hop): if hop.s_result.is_constant(): - return hop.inputconst(lltype.Bool, hop.s_result.const) + return hop.inputconst(ootype.Bool, hop.s_result.const) if hop.args_s[1].is_constant() and hop.args_s[1].const == list: if hop.args_s[0].knowntype != list: @@ -25,4 +47,8 @@ BUILTIN_TYPER = {} +BUILTIN_TYPER[ootype.new] = rtype_new +BUILTIN_TYPER[ootype.classof] = rtype_classof +BUILTIN_TYPER[ootype.runtimenew] = rtype_runtimenew +BUILTIN_TYPER[ootype.ooidentityhash] = rtype_ooidentityhash BUILTIN_TYPER[isinstance] = rtype_builtin_isinstance Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 18:27:22 2005 @@ -87,6 +87,12 @@ fielddefaults[mangled] = getattr(self.classdef.cls, name) except AttributeError: pass + # + # hash() support + if self.rtyper.needs_hash_support(self.classdef.cls): + from pypy.rpython import rint + allfields['_hash_cache_'] = rint.signed_repr + fields['_hash_cache_'] = ootype.Signed ootype.addFields(self.lowleveltype, fields) @@ -209,6 +215,19 @@ vinst, = hop.inputargs(self) return hop.genop('classof', [vinst], resulttype=ootype.Class) + 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.baserepr.rtype_hash(hop) + + def rtype_id(self, hop): + vinst, = hop.inputargs(self) + return hop.genop('ooidentityhash', [vinst], resulttype=ootype.Signed) + def convert_const(self, value): if value is None: return ootype.null(self.lowleveltype) @@ -246,12 +265,12 @@ def initialize_prebuilt_instance(self, value, result): # then add instance attributes from this level for mangled, (oot, default) in self.lowleveltype._allfields().items(): - name = unmangle(mangled) if oot is ootype.Void: llattrvalue = None - elif name == '_hash_cache_': # hash() support + elif mangled == '_hash_cache_': # hash() support llattrvalue = hash(value) else: + name = unmangle(mangled) try: attrvalue = getattr(value, name) except AttributeError: @@ -294,3 +313,10 @@ def rtype_ne(rpair, hop): v = rpair.rtype_eq(hop) return hop.genop("bool_not", [v], resulttype=ootype.Bool) + + +def ll_inst_hash(ins): + cached = ins._hash_cache_ + if cached == 0: + cached = ins._hash_cache_ = ootype.ooidentityhash(ins) + return cached Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 18:27:22 2005 @@ -436,3 +436,27 @@ assert res == ~0x0100 & 0x3ff res = interpret(f, [3], type_system='ootype') assert res == ~0x0200 & 0x3ff + +def test_hash_preservation(): + class C: + pass + class D(C): + pass + def f1(): + d2 = D() + # xxx we assume that the identityhash doesn't change from + # one line to the next + current_identityhash = id(d2) + instance_hash = hash(d2) + return current_identityhash == instance_hash + res = interpret(f1, [], type_system='ootype') + assert res is True + + c = C() + d = D() + def f2(): return hash(c) + def f3(): return hash(d) + res = interpret(f2, [], type_system='ootype') + assert res == hash(c) + res = interpret(f3, [], type_system='ootype') + assert res == hash(d) Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Wed Oct 19 18:27:22 2005 @@ -11,7 +11,6 @@ from pypy.rpython.rbool import bool_repr from pypy.rpython.rdict import rtype_r_dict from pypy.tool import sourcetools -from pypy.rpython.ootypesystem import ootype class __extend__(annmodel.SomeBuiltin): def rtyper_makerepr(self, rtyper): @@ -265,22 +264,6 @@ return hop.genop('runtime_type_info', vlist, resulttype = rptr.PtrRepr(lltype.Ptr(lltype.RuntimeTypeInfo))) -def rtype_new(hop): - assert hop.args_s[0].is_constant() - vlist = hop.inputargs(lltype.Void) - return hop.genop('new', vlist, - resulttype = hop.r_result.lowleveltype) - -def rtype_classof(hop): - assert isinstance(hop.args_s[0], annmodel.SomeOOInstance) - return hop.genop('classof', hop.args_v, - resulttype = ootype.Class) - -def rtype_runtimenew(hop): - assert isinstance(hop.args_s[0], annmodel.SomeOOClass) - return hop.genop('runtimenew', hop.args_v, - resulttype = hop.r_result.lowleveltype) - BUILTIN_TYPER[lltype.malloc] = rtype_malloc BUILTIN_TYPER[lltype.cast_pointer] = rtype_cast_pointer BUILTIN_TYPER[lltype.cast_ptr_to_int] = rtype_cast_ptr_to_int @@ -294,9 +277,6 @@ BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated BUILTIN_TYPER[objectmodel.hlinvoke] = rtype_hlinvoke -BUILTIN_TYPER[ootype.new] = rtype_new -BUILTIN_TYPER[ootype.classof] = rtype_classof -BUILTIN_TYPER[ootype.runtimenew] = rtype_runtimenew from pypy.rpython import extfunctable Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Wed Oct 19 18:27:22 2005 @@ -775,8 +775,9 @@ # build the 'direct_call' operation f = self.rtyper.getfunctionptr(spec_function) c = inputconst(typeOf(f), f) + fobj = self.rtyper.type_system_deref(f) return self.genop('direct_call', [c]+newargs_v, - resulttype = typeOf(f).TO.RESULT) + resulttype = typeOf(fobj).RESULT) def genexternalcall(self, fnname, args_v, resulttype=None, **flags): if isinstance(resulttype, Repr): From arigo at codespeak.net Wed Oct 19 18:51:37 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 18:51:37 +0200 (CEST) Subject: [pypy-svn] r18763 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051019165137.E40BB27B64@code1.codespeak.net> Author: arigo Date: Wed Oct 19 18:51:37 2005 New Revision: 18763 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: (mwh, arigo) * cleaned up test_ooclean.py ( :-) ) by removing the need for all these type_system='ootype' that are so easy to forget. Restored the check that the ootyped graphs have no pointers in them. * added a test, skipped for now (in-progress). Decided that ootype.classof() should probably crash on null instances. Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Oct 19 18:51:37 2005 @@ -276,6 +276,7 @@ def classof(inst): assert isinstance(inst, _instance) + assert bool(inst) return runtimeClass(inst._TYPE) def subclassof(class1, class2): Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 18:51:37 2005 @@ -1,20 +1,9 @@ from pypy.translator.translator import Translator from pypy.rpython import lltype from pypy.rpython.ootypesystem import ootype -from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython.test.test_llinterp import get_interpreter import py -def specialize(f, input_types, viewBefore=False, viewAfter=False): - t = Translator(f) - t.annotate(input_types) - if viewBefore: - t.view() - t.specialize(type_system="ootype") - if viewAfter: - t.view() - - graph = t.flowgraphs[f] - check_only_ootype(graph) def check_only_ootype(graph): def check_ootype(v): @@ -27,10 +16,20 @@ for const in block.getconstants(): check_ootype(const) +def interpret(func, values, view=False, viewbefore=False, policy=None, + someobjects=False): + interp = get_interpreter(func, values, view, viewbefore, policy, + someobjects, type_system='ootype') + for graph in interp.flowgraphs.values(): + check_only_ootype(graph) + return interp.eval_function(func, values) + +# ____________________________________________________________ + def test_simple(): def f(a, b): return a + b - result = interpret(f, [1, 2], type_system='ootype') + result = interpret(f, [1, 2]) assert result == 3 def test_simple_call(): @@ -39,7 +38,7 @@ def g(): return f(5, 3) - result = interpret(g, [], type_system='ootype') + result = interpret(g, []) assert result == 8 # Adjusted from test_rclass.py @@ -50,7 +49,7 @@ def dummyfn(): x = EmptyBase() return x - result = interpret(dummyfn, [], type_system='ootype') + result = interpret(dummyfn, []) assert isinstance(ootype.typeOf(result), ootype.Instance) @@ -59,7 +58,7 @@ x = EmptyBase() x.a = 1 return x.a - result = interpret(dummyfn, [], type_system='ootype') + result = interpret(dummyfn, []) assert result == 1 class Subclass(EmptyBase): @@ -73,7 +72,7 @@ y.a = 2 y.b = 3 return x.a + y.a + y.b - result = interpret(dummyfn, [], type_system='ootype') + result = interpret(dummyfn, []) assert result == 1 + 2 + 3 def test_polymorphic_field(): @@ -86,9 +85,9 @@ y = EmptyBase() y.a = 1 return y.a - result = interpret(dummyfn, [True], type_system='ootype') + result = interpret(dummyfn, [True]) assert result == 0 - result = interpret(dummyfn, [False], type_system='ootype') + result = interpret(dummyfn, [False]) assert result == 1 class HasAMethod(object): @@ -99,7 +98,7 @@ def dummyfn(): inst = HasAMethod() return inst.f() - result = interpret(dummyfn, [], type_system='ootype') + result = interpret(dummyfn, []) assert result == 1 class OverridesAMethod(HasAMethod): @@ -113,9 +112,9 @@ else: inst = OverridesAMethod() return inst.f() - result = interpret(dummyfn, [True], type_system='ootype') + result = interpret(dummyfn, [True]) assert result == 1 - result = interpret(dummyfn, [False], type_system='ootype') + result = interpret(dummyfn, [False]) assert result == 2 def test_method_used_in_subclasses_only(): @@ -127,7 +126,7 @@ def f(): x = B() return x.meth() - res = interpret(f, [], type_system='ootype') + res = interpret(f, []) assert res == 123 def test_method_both_A_and_B(): @@ -140,7 +139,7 @@ a = A() b = B() return a.meth() + b.meth() - res = interpret(f, [], type_system='ootype') + res = interpret(f, []) assert res == 246 class HasAField(object): @@ -152,7 +151,7 @@ inst.a = 3 def dummyfn(): return inst.f() - result = interpret(dummyfn, [], type_system='ootype') + result = interpret(dummyfn, []) assert result == 3 def test_recursive_prebuilt_instance(): @@ -164,7 +163,7 @@ b.peer = a def dummyfn(): return a.peer.peer.peer.x - res = interpret(dummyfn, [], type_system='ootype') + res = interpret(dummyfn, []) assert res == 6 def test_prebuilt_instances_with_void(): @@ -174,7 +173,7 @@ a.nothing_special = marker def dummyfn(): return a.nothing_special() - res = interpret(dummyfn, [], type_system='ootype') + res = interpret(dummyfn, []) assert res == 42 class HasClassAttr(object): @@ -189,7 +188,7 @@ def dummyfn(): inst = HasClassAttr() return inst.f(100) - result = interpret(dummyfn, [], type_system='ootype') + result = interpret(dummyfn, []) assert result == 103 def test_class_attr(): @@ -199,9 +198,9 @@ else: inst = OverridesClassAttr() return inst.f(100) - result = interpret(dummyfn, [True], type_system='ootype') + result = interpret(dummyfn, [True]) assert result == 103 - result = interpret(dummyfn, [False], type_system='ootype') + result = interpret(dummyfn, [False]) assert result == 142 def test_classattr_as_defaults(): @@ -211,7 +210,7 @@ x = MySubclass() x.a += 1 return x.a - res = interpret(dummyfn, [], type_system='ootype') + res = interpret(dummyfn, []) assert res == 4 def test_classattr_used_in_subclasses_only(): @@ -229,9 +228,9 @@ else: inst2 = SubSubclass2() return inst1.a + inst2.a - res = interpret(dummyfn, [True], type_system='ootype') + res = interpret(dummyfn, [True]) assert res == (3 + 42) + 3 - res = interpret(dummyfn, [False], type_system='ootype') + res = interpret(dummyfn, [False]) assert res == (3 + 42) + 5432 def test_name_clashes(): @@ -243,7 +242,7 @@ y = EmptyBase() y._TYPE = n+1 return x._TYPE() * y._TYPE - res = interpret(dummyfn, [6], type_system='ootype') + res = interpret(dummyfn, [6]) assert res == 42 def test_null_instance(): @@ -253,9 +252,9 @@ else: x = None return not x - res = interpret(dummyfn, [True], type_system='ootype') + res = interpret(dummyfn, [True]) assert res is False - res = interpret(dummyfn, [False], type_system='ootype') + res = interpret(dummyfn, [False]) assert res is True def test_isinstance(): @@ -275,13 +274,13 @@ else: o = C() return 100*isinstance(o, A)+10*isinstance(o, B)+1*isinstance(o ,C) - res = interpret(f, [1], type_system='ootype') + res = interpret(f, [1]) assert res == 100 - res = interpret(f, [2], type_system='ootype') + res = interpret(f, [2]) assert res == 110 - res = interpret(f, [3], type_system='ootype') + res = interpret(f, [3]) assert res == 111 - res = interpret(f, [0], type_system='ootype') + res = interpret(f, [0]) assert res == 0 def test_issubclass_type(): @@ -295,9 +294,9 @@ else: c1 = B() return issubclass(type(c1), B) - res = interpret(f, [0], type_system='ootype') + res = interpret(f, [0]) assert res is False - res = interpret(f, [1], type_system='ootype') + res = interpret(f, [1]) assert res is True def g(i): @@ -306,9 +305,9 @@ else: c1 = B() return issubclass(type(c1), A) - res = interpret(g, [0], type_system='ootype') + res = interpret(g, [0]) assert res is True - res = interpret(g, [1], type_system='ootype') + res = interpret(g, [1]) assert res is True def test_staticmethod(): @@ -317,7 +316,7 @@ def f(): a = A() return a.f(6, 7) - res = interpret(f, [], type_system='ootype') + res = interpret(f, []) assert res == 42 def test_instance_comparison(): @@ -328,9 +327,9 @@ else: b = EmptyBase() return (a is b)*100 + (a == b)*10 + (a != b) - res = interpret(f, [True], type_system='ootype') + res = interpret(f, [True]) assert res == 110 - res = interpret(f, [False], type_system='ootype') + res = interpret(f, [False]) assert res == 1 def test_is(): @@ -353,13 +352,13 @@ 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)) - res = interpret(f, [0], type_system='ootype') + res = interpret(f, [0]) assert res == 0x0004 - res = interpret(f, [1], type_system='ootype') + res = interpret(f, [1]) assert res == 0x0020 - res = interpret(f, [2], type_system='ootype') + res = interpret(f, [2]) assert res == 0x0100 - res = interpret(f, [3], type_system='ootype') + res = interpret(f, [3]) assert res == 0x0200 def test_eq(): @@ -382,13 +381,13 @@ 0x0008*(a == e) | 0x0010*(b == c) | 0x0020*(b == d) | 0x0040*(b == e) | 0x0080*(c == d) | 0x0100*(c == e) | 0x0200*(d == e)) - res = interpret(f, [0], type_system='ootype') + res = interpret(f, [0]) assert res == 0x0004 - res = interpret(f, [1], type_system='ootype') + res = interpret(f, [1]) assert res == 0x0020 - res = interpret(f, [2], type_system='ootype') + res = interpret(f, [2]) assert res == 0x0100 - res = interpret(f, [3], type_system='ootype') + res = interpret(f, [3]) assert res == 0x0200 def test_istrue(): @@ -403,9 +402,9 @@ return 1 else: return 2 - res = interpret(f, [0], type_system='ootype') + res = interpret(f, [0]) assert res == 1 - res = interpret(f, [1], type_system='ootype') + res = interpret(f, [1]) assert res == 2 def test_ne(): @@ -428,13 +427,13 @@ 0x0008*(a != e) | 0x0010*(b != c) | 0x0020*(b != d) | 0x0040*(b != e) | 0x0080*(c != d) | 0x0100*(c != e) | 0x0200*(d != e)) - res = interpret(f, [0], type_system='ootype') + res = interpret(f, [0]) assert res == ~0x0004 & 0x3ff - res = interpret(f, [1], type_system='ootype') + res = interpret(f, [1]) assert res == ~0x0020 & 0x3ff - res = interpret(f, [2], type_system='ootype') + res = interpret(f, [2]) assert res == ~0x0100 & 0x3ff - res = interpret(f, [3], type_system='ootype') + res = interpret(f, [3]) assert res == ~0x0200 & 0x3ff def test_hash_preservation(): @@ -449,14 +448,37 @@ current_identityhash = id(d2) instance_hash = hash(d2) return current_identityhash == instance_hash - res = interpret(f1, [], type_system='ootype') + res = interpret(f1, []) assert res is True c = C() d = D() def f2(): return hash(c) def f3(): return hash(d) - res = interpret(f2, [], type_system='ootype') + res = interpret(f2, []) assert res == hash(c) - res = interpret(f3, [], type_system='ootype') + res = interpret(f3, []) assert res == hash(d) + +def test_type(): + py.test.skip('in progress') + 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 tismer at codespeak.net Wed Oct 19 19:16:28 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Wed, 19 Oct 2005 19:16:28 +0200 (CEST) Subject: [pypy-svn] r18765 - pypy/dist/pypy/translator/c Message-ID: <20051019171628.D778C27B69@code1.codespeak.net> Author: tismer Date: Wed Oct 19 19:16:27 2005 New Revision: 18765 Modified: pypy/dist/pypy/translator/c/genc.py Log: made sure that line counting is always correct Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Wed Oct 19 19:16:27 2005 @@ -198,7 +198,7 @@ used = nextra part = [] for node in nodes: - impl = list(node.implementation()) + impl = '\n'.join(list(node.implementation())).split('\n') if not impl: continue cost = len(impl) + nbetween From pedronis at codespeak.net Wed Oct 19 19:28:01 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 19 Oct 2005 19:28:01 +0200 (CEST) Subject: [pypy-svn] r18766 - pypy/dist/pypy/annotation Message-ID: <20051019172801.E446927B6D@code1.codespeak.net> Author: pedronis Date: Wed Oct 19 19:27:58 2005 New Revision: 18766 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/listdef.py Log: use (possibly circual) chains of read_item/generalize for setitem(list,slice,value) and int*list/list*int preperation for special fixed-size lists support Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Wed Oct 19 19:27:58 2005 @@ -434,8 +434,7 @@ class __extend__(pairtype(SomeList, SomeInteger)): def mul((lst1, int2)): - #return getbookkeeper().newlist(lst1.listdef.read_item()) - return SomeList(lst1.listdef) + return lst1.listdef.offspring() def getitem((lst1, int2)): getbookkeeper().count("list_getitem", int2) @@ -456,8 +455,7 @@ class __extend__(pairtype(SomeList, SomeSlice)): def getitem((lst, slic)): - #return getbookkeeper().newlist(lst.listdef.read_item()) - return SomeList(lst.listdef) + return lst.listdef.offspring() getitem.can_only_throw = [] def setitem((lst, slic), s_iterable): @@ -496,8 +494,7 @@ class __extend__(pairtype(SomeInteger, SomeList)): def mul((int1, lst2)): - #return getbookkeeper().newlist(lst2.listdef.read_item()) - return SomeList(lst2.listdef) + return lst2.listdef.offspring() class __extend__(pairtype(SomeInstance, SomeInstance)): Modified: pypy/dist/pypy/annotation/listdef.py ============================================================================== --- pypy/dist/pypy/annotation/listdef.py (original) +++ pypy/dist/pypy/annotation/listdef.py Wed Oct 19 19:27:58 2005 @@ -78,13 +78,16 @@ self.listitem.itemof[self] = True self.bookkeeper = bookkeeper + def getbookkeeper(self): + if self.bookkeeper is None: + from pypy.annotation.bookkeeper import getbookkeeper + return getbookkeeper() + else: + return self.bookkeeper + def read_item(self, position_key=None): if position_key is None: - if self.bookkeeper is None: # for tests - from pypy.annotation.bookkeeper import getbookkeeper - position_key = getbookkeeper().position_key - else: - position_key = self.bookkeeper.position_key + position_key = self.getbookkeeper().position_key self.listitem.read_locations[position_key] = True return self.listitem.s_value @@ -105,13 +108,16 @@ self.generalize(s_other_value) other.generalize(s_self_value) - def offspring(self, other): + def offspring(self, *others): s_self_value = self.read_item() - s_other_value = other.read_item() - s_newlst = self.bookkeeper.newlist(s_self_value, s_other_value) + s_other_values = [] + for other in others: + s_other_values.append(other.read_item()) + s_newlst = self.getbookkeeper().newlist(s_self_value, *s_other_values) s_newvalue = s_newlst.listdef.read_item() self.generalize(s_newvalue) - other.generalize(s_newvalue) + for other in others: + other.generalize(s_newvalue) return s_newlst def generalize(self, s_value): From arigo at codespeak.net Wed Oct 19 19:57:39 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 19:57:39 +0200 (CEST) Subject: [pypy-svn] r18768 - in pypy/dist/pypy: annotation rpython rpython/ootypesystem rpython/ootypesystem/test Message-ID: <20051019175739.6299027B71@code1.codespeak.net> Author: arigo Date: Wed Oct 19 19:57:37 2005 New Revision: 18768 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/rootype.py pypy/dist/pypy/rpython/ootypesystem/rpbc.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py pypy/dist/pypy/rpython/rmodel.py Log: ootyper: * more operations needed by ll helpers ("oo helpers"?) on OOInstanceReprs: 'is' and truth-value testing. * introduced a NULL run-time class reference, returned by type(x) if x is an instance that turns out to be None. This supports the RPython style 'if type(x) is W_SuchAndSuch:...' * annotator support: SomeOOClass(None) for this NULL run-time class reference. * more annotator support: prebuilt oo classes and instances. * 'is' between classes. Requires a new operation 'oosameclass' :-/ * fix extremely confusing error message in the base Repr.rtype_is_(). * test_type() passes. Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Wed Oct 19 19:57:37 2005 @@ -695,8 +695,14 @@ class __extend__(pairtype(SomeOOClass, SomeOOClass)): def union((r1, r2)): - common = ootype.commonBaseclass(r1.ootype, r2.ootype) - assert common is not None, 'Mixing of incompatible classes %r, %r' %(r1.ootype, r2.ootype) + if r1.ootype is None: + common = r2.ootype + elif r2.ootype is None: + common = r1.ootype + else: + common = ootype.commonBaseclass(r1.ootype, r2.ootype) + assert common is not None, ('Mixing of incompatible classes %r, %r' + % (r1.ootype, r2.ootype)) return SomeOOClass(common) class __extend__(pairtype(SomeOOInstance, SomeObject)): Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Wed Oct 19 19:57:37 2005 @@ -15,7 +15,8 @@ from pypy.rpython.rarithmetic import r_uint from pypy.rpython.objectmodel import r_dict from pypy.tool.algo.unionfind import UnionFind -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype +from pypy.rpython.ootypesystem import ootype from pypy.rpython.memory import lladdress from pypy.annotation.specialize import decide_callable @@ -355,6 +356,10 @@ result= SomeAddress(is_null=True) elif isinstance(x, ootype._static_meth): result = SomeOOStaticMeth(ootype.typeOf(x)) + elif isinstance(x, ootype._class): + result = SomeOOClass(x._INSTANCE) # NB. can be None + elif isinstance(x, ootype._instance): + result = SomeOOInstance(ootype.typeOf(x)) elif callable(x) or isinstance(x, staticmethod): # XXX # maybe 'x' is a method bound to a not-yet-frozen cache? # fun fun fun. Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Wed Oct 19 19:57:37 2005 @@ -391,7 +391,10 @@ def runtimenew(c): assert isinstance(c, SomeOOClass) - return SomeOOInstance(c.ootype) + if c.ootype is None: + return SomeImpossibleValue() # can't call runtimenew(NULL) + else: + return SomeOOInstance(c.ootype) def ooidentityhash(i): assert isinstance(i, SomeOOInstance) Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 19 19:57:37 2005 @@ -670,6 +670,11 @@ def op_subclassof(self, class1, class2): return ootype.subclassof(class1, class2) + def op_oosameclass(self, class1, class2): + assert isinstance(class1, ootype._class) + assert isinstance(class2, ootype._class) + return class1 is class2 + def op_ooidentityhash(self, inst): return ootype.ooidentityhash(inst) Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Oct 19 19:57:37 2005 @@ -144,7 +144,8 @@ _TYPE = Class def __init__(self, INSTANCE): self._INSTANCE = INSTANCE - +nullruntimeclass = _class(None) + class _instance(object): def __init__(self, INSTANCE): @@ -256,6 +257,7 @@ def runtimenew(class_): assert isinstance(class_, _class) + assert class_ is not nullruntimeclass return _instance(class_._INSTANCE) def static_meth(FUNCTION, name, **attrs): @@ -282,6 +284,8 @@ def subclassof(class1, class2): assert isinstance(class1, _class) assert isinstance(class2, _class) + assert class1 is not nullruntimeclass + assert class2 is not nullruntimeclass return isSubclass(class1._INSTANCE, class2._INSTANCE) def addFields(INSTANCE, fields): Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 19:57:37 2005 @@ -38,6 +38,22 @@ return hop.genop('subclassof', vlist, resulttype=ootype.Bool) + def rtype_is_((r_cls1, r_cls2), hop): + class_repr = get_type_repr(self.rtyper) + vlist = hop.inputargs(class_repr, class_repr) + return hop.genop('oosameclass', vlist, resulttype=ootype.Bool) + + +def rtype_classes_is_(_, hop): + class_repr = get_type_repr(hop.rtyper) + vlist = hop.inputargs(class_repr, class_repr) + return hop.genop('oosameclass', vlist, resulttype=ootype.Bool) + +class __extend__(pairtype(ClassRepr, ClassRepr)): + rtype_is_ = rtype_classes_is_ + +# ____________________________________________________________ + def mangle(name): # XXX temporary: for now it looks like a good idea to mangle names # systematically to trap bugs related to a confusion between mangled @@ -213,7 +229,10 @@ def rtype_type(self, hop): vinst, = hop.inputargs(self) - return hop.genop('classof', [vinst], resulttype=ootype.Class) + if hop.args_s[0].can_be_none(): + return hop.gendirectcall(ll_inst_type, vinst) + else: + return hop.genop('classof', [vinst], resulttype=ootype.Class) def rtype_hash(self, hop): if self.classdef is None: @@ -320,3 +339,10 @@ if cached == 0: cached = ins._hash_cache_ = ootype.ooidentityhash(ins) return cached + +def ll_inst_type(obj): + if obj: + return ootype.classof(obj) + else: + # type(None) -> NULL (for now) + return ootype.nullruntimeclass Modified: pypy/dist/pypy/rpython/ootypesystem/rootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rootype.py Wed Oct 19 19:57:37 2005 @@ -1,5 +1,6 @@ from pypy.annotation import model as annmodel from pypy.rpython.rmodel import Repr +from pypy.rpython.ootypesystem import ootype from pypy.rpython.ootypesystem.ootype import Void, Class from pypy.annotation.pairtype import pairtype @@ -47,6 +48,18 @@ vlist = hop.inputargs(self, Void, hop.args_r[2]) return hop.genop('oosetfield', vlist) + def rtype_is_true(self, hop): + vlist = hop.inputargs(self) + return hop.genop('oononnull', vlist, resulttype=ootype.Bool) + + +class __extend__(pairtype(OOInstanceRepr, OOInstanceRepr)): + def rtype_is_((r_ins1, r_ins2), hop): + # NB. this version performs no cast to the common base class + vlist = hop.inputargs(r_ins1, r_ins2) + return hop.genop('oois', vlist, resulttype=ootype.Bool) + + class OOBoundMethRepr(Repr): def __init__(self, ootype, name): self.lowleveltype = ootype Modified: pypy/dist/pypy/rpython/ootypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rpbc.py Wed Oct 19 19:57:37 2005 @@ -1,7 +1,8 @@ from pypy.rpython.rpbc import AbstractClassesPBCRepr, AbstractMethodsPBCRepr from pypy.rpython.rclass import rtype_new_instance from pypy.rpython.ootypesystem import ootype -from pypy.rpython.ootypesystem.rclass import InstanceRepr, mangle +from pypy.rpython.ootypesystem.rclass import ClassRepr, InstanceRepr, mangle +from pypy.rpython.ootypesystem.rclass import rtype_classes_is_ from pypy.annotation.pairtype import pairtype class ClassesPBCRepr(AbstractClassesPBCRepr): @@ -29,3 +30,10 @@ def convert_from_to(_, v, llops): return v + + +class __extend__(pairtype(ClassRepr, ClassesPBCRepr)): + rtype_is_ = rtype_classes_is_ + +class __extend__(pairtype(ClassesPBCRepr, ClassRepr)): + rtype_is_ = rtype_classes_is_ Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooann.py Wed Oct 19 19:57:37 2005 @@ -146,3 +146,16 @@ assert s.knowntype == int +def test_truth_value(): + C = Instance("C", None) + def oof(f): + if f: + c = new(C) + else: + c = null(C) + return not c + + a = RPythonAnnotator() + s = a.build_types(oof, [bool]) + assert isinstance(s, annmodel.SomeBool) + assert not s.is_constant() Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 19:57:37 2005 @@ -461,7 +461,6 @@ assert res == hash(d) def test_type(): - py.test.skip('in progress') class A: pass class B(A): Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_oortype.py Wed Oct 19 19:57:37 2005 @@ -3,6 +3,7 @@ from pypy.annotation import model as annmodel from pypy.objspace.flow import FlowObjSpace from pypy.translator.translator import Translator +from pypy.rpython.test.test_llinterp import interpret def gengraph(f, args=[], viewBefore=False, viewAfter=False): t = Translator(f) @@ -52,3 +53,22 @@ g = gengraph(f) rettype = g.getreturnvar().concretetype assert rettype == Signed + +def test_truth_value(): + C = Instance("C", None) + NULL = null(C) + def oof(f): + if f: + c = new(C) + else: + c = NULL + return not c + + g = gengraph(oof, [bool]) + rettype = g.getreturnvar().concretetype + assert rettype == Bool + + res = interpret(oof, [True], type_system='ootype') + assert res is False + res = interpret(oof, [False], type_system='ootype') + assert res is True Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Wed Oct 19 19:57:37 2005 @@ -199,6 +199,8 @@ def rtype_is_((robj1, robj2), hop): if hop.s_result.is_constant(): return inputconst(Bool, hop.s_result.const) + roriginal1 = robj1 + roriginal2 = robj2 if robj1.lowleveltype is Void: robj1 = robj2 elif robj2.lowleveltype is Void: @@ -206,10 +208,10 @@ if (not isinstance(robj1.lowleveltype, Ptr) or not isinstance(robj2.lowleveltype, Ptr)): raise TyperError('is of instances of the non-pointers: %r, %r' % ( - robj1, robj2)) + roriginal1, roriginal2)) if robj1.lowleveltype != robj2.lowleveltype: raise TyperError('is of instances of different pointer types: %r, %r' % ( - robj1, robj2)) + roriginal1, roriginal2)) v_list = hop.inputargs(robj1, robj2) return hop.genop('ptr_eq', v_list, resulttype=Bool) From mwh at codespeak.net Wed Oct 19 20:04:58 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 19 Oct 2005 20:04:58 +0200 (CEST) Subject: [pypy-svn] r18769 - pypy/extradoc/planning Message-ID: <20051019180458.6649A27B74@code1.codespeak.net> Author: mwh Date: Wed Oct 19 20:04:57 2005 New Revision: 18769 Modified: pypy/extradoc/planning/phase2_projectactivities.txt Log: add estimated completion dates by taking the date from the minutes of the consortium meeting and adding a week for the review process. feel free to yelp. also feel free to finish early :) Modified: pypy/extradoc/planning/phase2_projectactivities.txt ============================================================================== --- pypy/extradoc/planning/phase2_projectactivities.txt (original) +++ pypy/extradoc/planning/phase2_projectactivities.txt Wed Oct 19 20:04:57 2005 @@ -180,35 +180,35 @@ D04.1 Partial Python Impl: Primary/Secondary: Jacob / Christian -Completion date: +Completion date: 28th Oct 2005 D04.2 Complete Python Impl: Primary/Secondary: Jacob / Christian -Completion date: +Completion date: 4th Nov 2005 D04.3 Parser report: Primary/Secondary: ludovic,adrien / Arre -Completion date: +Completion date: 11th Nov 2005 D04.4 Release PyPy-research-tool: Primary/Secondary: Samuele / Ludovic -Completion date: +Completion date: 11th Nov 2005 D05.1 Publish on translating a very-high-level description: Primary/Secondary: Armin / Michael -Completion date: +Completion date: 4th Nov 2005 D05.2 A compiled, self-contained version of PyPy: Primary/Secondary: dfki/Anders L. / Jacob -Completion date: +Completion date: 28th Oct 2005 D05.3 Publish on implementation with translation aspects: Primary/Secondary: Carl / Armin, Christian -Completion date: +Completion date: TBA D05.4 Publish on encapsulating low level language aspects: Primary/Secondary: Armin / holger -Completion date: +Completion date: TBA D14.1 Report about Milestone/Phase 1: Primary/Secondary: Bea/Stephan From mwh at codespeak.net Wed Oct 19 20:12:16 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 19 Oct 2005 20:12:16 +0200 (CEST) Subject: [pypy-svn] r18770 - pypy/extradoc/planning Message-ID: <20051019181216.0832D27B7A@code1.codespeak.net> Author: mwh Date: Wed Oct 19 20:12:15 2005 New Revision: 18770 Modified: pypy/extradoc/planning/phase2_projectactivities.txt Log: the WHAT of february? :) Modified: pypy/extradoc/planning/phase2_projectactivities.txt ============================================================================== --- pypy/extradoc/planning/phase2_projectactivities.txt (original) +++ pypy/extradoc/planning/phase2_projectactivities.txt Wed Oct 19 20:12:15 2005 @@ -77,8 +77,9 @@ *23-29th January: CS Dep. of the Palma de Mallorca University/CS Dep. of the Barcelona University Bea check dates, Bruxelles/Louvain-la-neuve, Holger check dates), - *27-29th February: PyCon (24-26 Feb, 2006 Dallas, Texas, postsprint, - Michael/Holger, Armin, Christian, Bea), DEADLINE 30th October + *27 Feb - 1st March: PyCon (24-26 Feb, 2006 Dallas, Texas, + postsprint, Michael/Holger, Armin, Christian, Bea), DEADLINE 30th + October *April Japan: (1) April 23 to April 29, (2) April 30 to May 5, contact: Yutaka Niibe, National Institute of AIST, Japan (FSIJ) Akihabara, Tokyo (Bea), venue for 32 people. From arigo at codespeak.net Wed Oct 19 20:14:54 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 20:14:54 +0200 (CEST) Subject: [pypy-svn] r18771 - in pypy/dist/pypy/rpython: . ootypesystem ootypesystem/test Message-ID: <20051019181454.B740327B7A@code1.codespeak.net> Author: arigo Date: Wed Oct 19 20:14:53 2005 New Revision: 18771 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: The last test from the lltyper's test_rclass.py: llinterpreting void fields. Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 19 20:14:53 2005 @@ -631,7 +631,9 @@ def op_oosetfield(self, inst, name, value): assert isinstance(inst, ootype._instance) assert isinstance(name, str) - setattr(inst, name, value) + FIELDTYPE = self.llt.typeOf(inst)._field_type(name) + if FIELDTYPE != self.llt.Void: + setattr(inst, name, value) def op_oogetfield(self, inst, name): assert isinstance(inst, ootype._instance) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Wed Oct 19 20:14:53 2005 @@ -219,7 +219,8 @@ attr = hop.args_s[1].const mangled = mangle(attr) self.lowleveltype._check_field(mangled) - v_inst, _, v_newval = hop.inputargs(self, ootype.Void, hop.args_r[2]) + r_value = self.allfields[mangled] + v_inst, _, v_newval = hop.inputargs(self, ootype.Void, r_value) v_attr = hop.inputconst(ootype.Void, mangled) return hop.genop('oosetfield', [v_inst, v_attr, v_newval]) Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Wed Oct 19 20:14:53 2005 @@ -481,3 +481,13 @@ assert res is False res = interpret(f, [0]) assert res is False + +def test_void_fnptr(): + def g(): + return 42 + def f(): + e = EmptyBase() + e.attr = g + return e.attr() + res = interpret(f, []) + assert res == 42 From arigo at codespeak.net Wed Oct 19 20:31:10 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 20:31:10 +0200 (CEST) Subject: [pypy-svn] r18773 - in pypy/dist/pypy/interpreter: . test Message-ID: <20051019183110.3958C27B85@code1.codespeak.net> Author: arigo Date: Wed Oct 19 20:31:09 2005 New Revision: 18773 Modified: pypy/dist/pypy/interpreter/function.py pypy/dist/pypy/interpreter/test/test_function.py Log: issue143 resolved FuncType() should indeed accept None as the func_closure argument. Thanks Lenard for the bug report and proposed patch! Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Wed Oct 19 20:31:09 2005 @@ -50,7 +50,7 @@ # unwrapping is done through unwrap_specs in typedef.py def descr_method__new__(space, w_subtype, w_code, w_globals, - w_name=None, w_argdefs=None, w_closure=NoneNotWrapped): + w_name=None, w_argdefs=None, w_closure=None): code = space.interpclass_w(w_code) if code is None or not isinstance(code, Code): raise OperationError(space.w_TypeError, space.wrap("expected code")) @@ -64,7 +64,7 @@ defs_w = space.unpackiterable(w_argdefs) else: defs_w = [] - if w_closure is None: + if space.is_w(w_closure, space.w_None): closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) Modified: pypy/dist/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_function.py (original) +++ pypy/dist/pypy/interpreter/test/test_function.py Wed Oct 19 20:31:09 2005 @@ -55,6 +55,12 @@ del f.__module__ assert f.__module__ is None + def test_new(self): + def f(): return 42 + FuncType = type(f) + f2 = FuncType(f.func_code, f.func_globals, 'f2', None, None) + assert f2() == 42 + class AppTestFunction: def test_simple_call(self): def func(arg1, arg2): From rxe at codespeak.net Wed Oct 19 20:32:36 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 19 Oct 2005 20:32:36 +0200 (CEST) Subject: [pypy-svn] r18774 - pypy/dist/pypy/translator/llvm Message-ID: <20051019183236.EF13227B88@code1.codespeak.net> Author: rxe Date: Wed Oct 19 20:32:34 2005 New Revision: 18774 Modified: pypy/dist/pypy/translator/llvm/gc.py Log: For some reason, after upgrading ubuntu, I need to include pthread when using boehm gc. Modified: pypy/dist/pypy/translator/llvm/gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/gc.py (original) +++ pypy/dist/pypy/translator/llvm/gc.py Wed Oct 19 20:32:34 2005 @@ -56,7 +56,7 @@ self.n_malloced = 0 def gc_libraries(self): - return ['gc'] # xxx on windows? + return ['gc', 'pthread'] # XXX on windows? def declarations(self): return ''' From rxe at codespeak.net Wed Oct 19 20:35:25 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 19 Oct 2005 20:35:25 +0200 (CEST) Subject: [pypy-svn] r18775 - pypy/dist/pypy/translator/llvm/module Message-ID: <20051019183525.2522527B8C@code1.codespeak.net> Author: rxe Date: Wed Oct 19 20:35:23 2005 New Revision: 18775 Modified: pypy/dist/pypy/translator/llvm/module/support.py Log: Ooops - dont guess predeclared types if we already know them. Modified: pypy/dist/pypy/translator/llvm/module/support.py ============================================================================== --- pypy/dist/pypy/translator/llvm/module/support.py (original) +++ pypy/dist/pypy/translator/llvm/module/support.py Wed Oct 19 20:35:23 2005 @@ -269,7 +269,7 @@ int %main(int %argc, sbyte** %argv) { entry: store int 0, int* %GC_all_interior_pointers - %pypy_argv = call fastcc %structtype.list* %pypy__RPyListOfString_New__Signed(int %argc) + %pypy_argv = call fastcc %RPyListOfString* %pypy__RPyListOfString_New__Signed(int %argc) br label %no_exit no_exit: @@ -278,14 +278,14 @@ %tmp.8 = getelementptr sbyte** %argv, uint %indvar %tmp.9 = load sbyte** %tmp.8 %rpy = call fastcc %RPyString* %RPyString_FromString(sbyte* %tmp.9) - call fastcc void %pypy__RPyListOfString_SetItem__listPtr_Signed_rpy_stringPtr(%structtype.list* %pypy_argv, int %i.0.0, %RPyString* %rpy) + call fastcc void %pypy__RPyListOfString_SetItem__listPtr_Signed_rpy_stringPtr(%RPyListOfString* %pypy_argv, int %i.0.0, %RPyString* %rpy) %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 = call fastcc int %pypy_entry_point(%RPyListOfString* %pypy_argv) ret int %ret } """] From rxe at codespeak.net Wed Oct 19 20:52:56 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 19 Oct 2005 20:52:56 +0200 (CEST) Subject: [pypy-svn] r18776 - pypy/dist/pypy/translator/llvm Message-ID: <20051019185256.6E94827B8C@code1.codespeak.net> Author: rxe Date: Wed Oct 19 20:52:53 2005 New Revision: 18776 Modified: pypy/dist/pypy/translator/llvm/arraynode.py pypy/dist/pypy/translator/llvm/structnode.py pypy/dist/pypy/translator/llvm/varsize.py Log: Take the rest of fields in to account when mallocing varsize structs (was only using the array.) ASFAIK (without checking) - this is not actually needed, but heh, saves it biting us on the a%#e if it does. ;-) Modified: pypy/dist/pypy/translator/llvm/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm/arraynode.py Wed Oct 19 20:52:53 2005 @@ -56,7 +56,8 @@ log.writeimpl(self.ref) varsize.write_constructor(self.db, codewriter, self.ref, self.constructor_decl, - self.array) + self.array, + atomic=self.array._is_atomic()) class VoidArrayTypeNode(LLVMNode): Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Wed Oct 19 20:52:53 2005 @@ -77,7 +77,8 @@ self.ref, self.constructor_decl, current, - indices_to_array) + indices_to_array, + self.struct._is_atomic()) 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 Wed Oct 19 20:52:53 2005 @@ -1,7 +1,7 @@ from pypy.rpython.rstr import STR def write_constructor(db, codewriter, ref, constructor_decl, ARRAY, - indices_to_array=()): + indices_to_array=(), atomic=False): #varsized arrays and structs look like this: #Array: {int length , elemtype*} @@ -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=ARRAY._is_atomic()) + codewriter.malloc("%ptr", "sbyte", "%usize", atomic=atomic) codewriter.cast("%result", "sbyte*", "%ptr", ref + "*") indices_to_arraylength = tuple(indices_to_array) + (("uint", 0),) From rxe at codespeak.net Wed Oct 19 22:28:18 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Wed, 19 Oct 2005 22:28:18 +0200 (CEST) Subject: [pypy-svn] r18777 - pypy/dist/pypy/translator/llvm Message-ID: <20051019202818.84DDD27B48@code1.codespeak.net> Author: rxe Date: Wed Oct 19 22:28:16 2005 New Revision: 18777 Modified: pypy/dist/pypy/translator/llvm/opwriter.py Log: RPython doesnt support this anymore. Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Wed Oct 19 22:28:16 2005 @@ -48,7 +48,6 @@ 'float_add': 'add', 'float_sub': 'sub', 'float_truediv': 'div', - 'float_mod': 'rem', 'float_lt': 'setlt', 'float_le': 'setle', 'float_eq': 'seteq', From arigo at codespeak.net Wed Oct 19 22:45:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 22:45:18 +0200 (CEST) Subject: [pypy-svn] r18778 - pypy/dist/pypy/tool Message-ID: <20051019204518.E653627B64@code1.codespeak.net> Author: arigo Date: Wed Oct 19 22:45:18 2005 New Revision: 18778 Modified: pypy/dist/pypy/tool/sourcetools.py Log: uh? Modified: pypy/dist/pypy/tool/sourcetools.py ============================================================================== --- pypy/dist/pypy/tool/sourcetools.py (original) +++ pypy/dist/pypy/tool/sourcetools.py Wed Oct 19 22:45:18 2005 @@ -209,8 +209,7 @@ # ____________________________________________________________ -if (sys.version_info >= (2, 3) and - not hasattr(sys, 'pypy_objspaceclass')): +if sys.version_info >= (2, 3): def func_with_new_name(func, newname): """Make a renamed copy of a function.""" f = new.function(func.func_code, func.func_globals, From arigo at codespeak.net Wed Oct 19 23:14:21 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 19 Oct 2005 23:14:21 +0200 (CEST) Subject: [pypy-svn] r18780 - in pypy/dist/pypy: objspace/std translator translator/goal Message-ID: <20051019211421.0A55427B66@code1.codespeak.net> Author: arigo Date: Wed Oct 19 23:14:20 2005 New Revision: 18780 Modified: pypy/dist/pypy/objspace/std/fake.py pypy/dist/pypy/translator/geninterplevel.py pypy/dist/pypy/translator/goal/app_main.py Log: details fixed to allow pypy-c to run a bit more of py.py before crashing. Modified: pypy/dist/pypy/objspace/std/fake.py ============================================================================== --- pypy/dist/pypy/objspace/std/fake.py (original) +++ pypy/dist/pypy/objspace/std/fake.py Wed Oct 19 23:14:20 2005 @@ -249,5 +249,6 @@ baseobjspace.W_Root]), ) -_fake_type_cache[type(file.softspace)] = W_FakeDescriptor +if hasattr(file, 'softspace'): # CPython only + _fake_type_cache[type(file.softspace)] = W_FakeDescriptor _fake_type_cache[type(type.__dict__['__dict__'])] = W_FakeDescriptor Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Wed Oct 19 23:14:20 2005 @@ -192,9 +192,10 @@ # with modified builtins # add a dummy _issubtype() to builtins - def _issubtype(cls1, cls2): - raise TypeError, "this dummy should *not* be reached" - __builtin__._issubtype = _issubtype + if not hasattr(__builtin__, '_issubtype'): + def _issubtype(cls1, cls2): + raise TypeError, "this dummy should *not* be reached" + __builtin__._issubtype = _issubtype class bltinstub: def __init__(self, name): 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 Wed Oct 19 23:14:20 2005 @@ -182,7 +182,7 @@ print >> sys.stderr, "debug: calling code.interact()" run_toplevel(code.interact, local=mainmodule.__dict__) except SystemExit, e: - return e.exitcode + return e.code else: return 0 From arigo at codespeak.net Thu Oct 20 00:23:02 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 00:23:02 +0200 (CEST) Subject: [pypy-svn] r18781 - in pypy/dist/pypy/interpreter: astcompiler test Message-ID: <20051019222302.7276227B5A@code1.codespeak.net> Author: arigo Date: Thu Oct 20 00:23:01 2005 New Revision: 18781 Modified: 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/test/test_compiler.py Log: More compiler bugs! Cool! Blah blah name mangling blah. Yes I know I should not write check-in messages after midnight. Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Thu Oct 20 00:23:01 2005 @@ -434,8 +434,8 @@ class PyFlowGraph(FlowGraph): - def __init__(self, space, name, filename, args=None, optimized=0, - klass=0, newlocals=0): + def __init__(self, space, name, filename, args=None, mangler=None, + optimized=0, klass=0, newlocals=0): FlowGraph.__init__(self, space) if args is None: args = [] @@ -465,7 +465,7 @@ for i in range(len(args)): var = args[i] if isinstance(var, ast.AssName): - self.varnames.append(var.name ) + self.varnames.append(mangler.mangle(var.name)) elif isinstance(var, ast.AssTuple): self.varnames.append('.%d' % (2 * i)) self.stage = RAW Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Thu Oct 20 00:23:01 2005 @@ -146,6 +146,7 @@ """ scopeambiguity = False + class_name = "" def __init__(self, space, graph): self.space = space @@ -155,7 +156,6 @@ self.genexpr_cont_stack = [] self.graph = graph self.optimized = 0 # is namespace access optimized? - self.class_name = "" # provide default for instance variable # XXX set flags based on future features futures = self.get_module().futures @@ -236,7 +236,7 @@ def delName(self, name, lineno): if name in ('None', '__debug__'): raise SyntaxError('deleting %s is not allowed' % name, lineno) - scope = self.scope.check_name(name) + scope = self.scope.check_name(self.mangle(name)) if scope == SC_CELL: raise SyntaxError("can not delete variable '%s' " "referenced in nested scope" % name, lineno) @@ -1238,6 +1238,7 @@ class AbstractFunctionCode(CodeGenerator): def __init__(self, space, func, isLambda, class_name, mod): + self.class_name = class_name self.module = mod if isLambda: name = "" @@ -1248,11 +1249,13 @@ argnames = {} for arg in func.argnames: if isinstance(arg, ast.AssName): - if arg.name in argnames: - raise SyntaxError("duplicate argument '%s' in function definition" % arg.name, func.lineno) - argnames[arg.name] = 1 + argname = self.mangle(arg.name) + if argname in argnames: + raise SyntaxError("duplicate argument '%s' in function definition" % argname, func.lineno) + argnames[argname] = 1 elif isinstance(arg, ast.AssTuple): for argname in arg.getArgNames(): + argname = self.mangle(argname) if argname in argnames: raise SyntaxError("duplicate argument '%s' in function definition" % argname, func.lineno) argnames[argname] = 1 @@ -1260,11 +1263,11 @@ raise SyntaxError('assignment to None is not allowed', func.lineno) graph = pyassem.PyFlowGraph(space, name, func.filename, func.argnames, + mangler=self, optimized=self.localsfullyknown, newlocals=1) self.isLambda = isLambda CodeGenerator.__init__(self, space, graph) - self.class_name = class_name self.optimized = 1 if not isLambda and not space.is_w(func.doc, space.w_None): Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Thu Oct 20 00:23:01 2005 @@ -157,6 +157,7 @@ """ child_globals = [] for name in names: + name = self.mangle(name) sc = self.check_name(name) if self.nested: if sc == SC_UNKNOWN or sc == SC_FREE \ @@ -416,6 +417,7 @@ def visitGlobal(self, node ): scope = self.cur_scope() for name in node.names: + name = scope.mangle(name) namescope = scope.check_name(name) if namescope == SC_LOCAL: issue_warning(self.space, "name '%s' is assigned to before " 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 Oct 20 00:23:01 2005 @@ -338,6 +338,36 @@ assert space.int_w(w_fline) == 2 assert space.int_w(w_gline) == 6 + def test_mangling(self): + snippet = str(py.code.Source(r''' + __g = "42" + class X: + def __init__(self, u): + self.__u = u + def __f(__self, __n): + global __g + __NameError = NameError + try: + yield "found: " + __g + except __NameError, __e: + yield "not found: " + str(__e) + del __NameError + for __i in range(__self.__u * __n): + yield locals() + result = X(2) + assert not hasattr(result, "__f") + result = list(result._X__f(3)) + assert len(result) == 7 + assert result[0].startswith("not found: ") + for d in result[1:]: + for key, value in d.items(): + assert not key.startswith('__') + ''')) + code = self.compiler.compile(snippet, '', 'exec', 0) + space = self.space + w_d = space.newdict([]) + space.exec_(code, w_d, w_d) + class TestECCompiler(BaseTestCompiler): def setup_method(self, method): self.compiler = self.space.getexecutioncontext().compiler From cfbolz at codespeak.net Thu Oct 20 00:47:49 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Oct 2005 00:47:49 +0200 (CEST) Subject: [pypy-svn] r18782 - pypy/dist/pypy/tool Message-ID: <20051019224749.660DD27B6A@code1.codespeak.net> Author: cfbolz Date: Thu Oct 20 00:47:48 2005 New Revision: 18782 Added: pypy/dist/pypy/tool/statistic_over_time.py Log: little tool that calculates some information about our codebase for every day Added: pypy/dist/pypy/tool/statistic_over_time.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/statistic_over_time.py Thu Oct 20 00:47:48 2005 @@ -0,0 +1,44 @@ +import py +from py.__.misc.cmdline.countloc import get_loccount +import datetime +import time + +try: + path = py.path.svnwc(py.std.sys.argv[1]) +except IndexError: + path = py.path.svnwc() + +tempdir = py.path.svnwc(py.test.ensuretemp("pypy-dist")) +print "checking out" +tempdir.checkout("http://codespeak.net/svn/pypy/dist") +print "done" +pypy = tempdir.join('pypy') + +class DailyStatistic(object): + pass + +statistic = [] + +curr_rev = tempdir.info().rev + +while curr_rev > 1: + num_revs = 0 + num_files = 0 + num_testfiles = 0 + num_lines = 0 + num_testlines = 0 + curr_rev = tempdir.info(usecache=0).rev + olddate = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) + date = olddate + while date == olddate: + counter, nf, nl, ntf, ntl = get_loccount([pypy.localpath]) + num_revs += 1 + num_files = max(num_files, nf) + num_testfiles = max(num_testfiles, ntf) + num_lines = max(num_lines, nl) + num_testlines = max(num_testlines, ntl) + olddate = date + tempdir.update(rev=curr_rev - 2) + curr_rev = tempdir.info(usecache=0).rev + date = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) + print date, num_revs, num_files, num_testfiles, num_lines, num_testlines From cfbolz at codespeak.net Thu Oct 20 10:49:49 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Oct 2005 10:49:49 +0200 (CEST) Subject: [pypy-svn] r18784 - pypy/dist/pypy/tool Message-ID: <20051020084949.CDBB327B5D@code1.codespeak.net> Author: cfbolz Date: Thu Oct 20 10:49:48 2005 New Revision: 18784 Modified: pypy/dist/pypy/tool/statistic_over_time.py Log: sometimes it is necessary to delete a dir a do a new checkout Modified: pypy/dist/pypy/tool/statistic_over_time.py ============================================================================== --- pypy/dist/pypy/tool/statistic_over_time.py (original) +++ pypy/dist/pypy/tool/statistic_over_time.py Thu Oct 20 10:49:48 2005 @@ -8,9 +8,11 @@ except IndexError: path = py.path.svnwc() +URL = "http://codespeak.net/svn/pypy/dist" + tempdir = py.path.svnwc(py.test.ensuretemp("pypy-dist")) print "checking out" -tempdir.checkout("http://codespeak.net/svn/pypy/dist") +tempdir.checkout(URL) print "done" pypy = tempdir.join('pypy') @@ -38,7 +40,18 @@ num_lines = max(num_lines, nl) num_testlines = max(num_testlines, ntl) olddate = date - tempdir.update(rev=curr_rev - 2) + try: + tempdir.update(rev=curr_rev - 1) + except: + tempdir.localpath.remove(1) + tempdir.localpath.makedir() + tempdir.checkout(URL, rev=curr_rev - 1) curr_rev = tempdir.info(usecache=0).rev date = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) print date, num_revs, num_files, num_testfiles, num_lines, num_testlines + statistic.append([date, num_revs, num_files, num_testfiles, num_lines, num_testlines]) + +import pickle +f = file("out.txt", "w") +pickle.dump(statistic, f) +f.close() From cfbolz at codespeak.net Thu Oct 20 11:22:03 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Oct 2005 11:22:03 +0200 (CEST) Subject: [pypy-svn] r18786 - pypy/dist/pypy/tool Message-ID: <20051020092203.3694627B5D@code1.codespeak.net> Author: cfbolz Date: Thu Oct 20 11:22:01 2005 New Revision: 18786 Modified: pypy/dist/pypy/tool/statistic_over_time.py Log: be a bit more careful... Modified: pypy/dist/pypy/tool/statistic_over_time.py ============================================================================== --- pypy/dist/pypy/tool/statistic_over_time.py (original) +++ pypy/dist/pypy/tool/statistic_over_time.py Thu Oct 20 11:22:01 2005 @@ -23,35 +23,36 @@ curr_rev = tempdir.info().rev -while curr_rev > 1: - num_revs = 0 - num_files = 0 - num_testfiles = 0 - num_lines = 0 - num_testlines = 0 - curr_rev = tempdir.info(usecache=0).rev - olddate = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) - date = olddate - while date == olddate: - counter, nf, nl, ntf, ntl = get_loccount([pypy.localpath]) - num_revs += 1 - num_files = max(num_files, nf) - num_testfiles = max(num_testfiles, ntf) - num_lines = max(num_lines, nl) - num_testlines = max(num_testlines, ntl) - olddate = date - try: - tempdir.update(rev=curr_rev - 1) - except: - tempdir.localpath.remove(1) - tempdir.localpath.makedir() - tempdir.checkout(URL, rev=curr_rev - 1) +try: + while curr_rev > 1: + num_revs = 0 + num_files = 0 + num_testfiles = 0 + num_lines = 0 + num_testlines = 0 curr_rev = tempdir.info(usecache=0).rev - date = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) - print date, num_revs, num_files, num_testfiles, num_lines, num_testlines - statistic.append([date, num_revs, num_files, num_testfiles, num_lines, num_testlines]) - -import pickle -f = file("out.txt", "w") -pickle.dump(statistic, f) -f.close() + olddate = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) + date = olddate + while date == olddate: + counter, nf, nl, ntf, ntl = get_loccount([pypy.localpath]) + num_revs += 1 + num_files = max(num_files, nf) + num_testfiles = max(num_testfiles, ntf) + num_lines = max(num_lines, nl) + num_testlines = max(num_testlines, ntl) + olddate = date + try: + tempdir.update(rev=curr_rev - 1) + except: + tempdir.localpath.remove(1) + tempdir.localpath.mkdir() + tempdir.checkout(URL, rev=curr_rev - 1) + curr_rev = tempdir.info(usecache=0).rev + date = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) + print date, num_revs, num_files, num_testfiles, num_lines, num_testlines + statistic.append([date, num_revs, num_files, num_testfiles, num_lines, num_testlines]) +finally: + import pickle + f = file("out.txt", "w") + pickle.dump(statistic, f) + f.close() From arigo at codespeak.net Thu Oct 20 11:47:19 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 11:47:19 +0200 (CEST) Subject: [pypy-svn] r18787 - in pypy/dist/pypy/rpython/ootypesystem: . test Message-ID: <20051020094719.7D98127B5D@code1.codespeak.net> Author: arigo Date: Thu Oct 20 11:47:18 2005 New Revision: 18787 Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Log: ootyper: abstract base methods Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Thu Oct 20 11:47:18 2005 @@ -73,10 +73,11 @@ # _add_fields adds *descriptions* of fields. This is obvious # if you are in the right state of mind (swiss?), but # certainly not necessarily if not. + # NB. a None method is a purely abstract one. for name, method in methods.iteritems(): if self._has_field(name): raise TypeError("Can't add method %r: field already exists" % name) - if not isinstance(typeOf(method), Meth): + if method is not None and not isinstance(typeOf(method), Meth): raise TypeError("added methods must be _meths, not %s" % type(defn)) self._methods.update(methods) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Thu Oct 20 11:47:18 2005 @@ -123,9 +123,15 @@ if not attrdef.readonly: continue mangled = mangle(name) + is_method = (classrepr.prepare_method(attrdef.s_value) + is not None) if mangled in allmethods or mangled in allclassattributes: # if the method/attr was already found in a parent class, # we register it again only if it is overridden. + if is_method and mangled in allclassattributes: + raise TyperError("method overrides class attribute") + if not is_method and mangled in allmethods: + raise TyperError("class attribute overrides method") if name not in self.classdef.cls.__dict__: continue impl = self.classdef.cls.__dict__[name] @@ -138,14 +144,21 @@ impl = clsdef.cls.__dict__[name] break else: - raise TyperError("class %r has no attribute %r" % ( - self.classdef.cls, name)) - if classrepr.prepare_method(attrdef.s_value) is not None: + if is_method: + impl = None # abstract base method + else: + raise TyperError("class %r has no attribute %r" % ( + self.classdef.cls, name)) + if is_method: # a regular method - f, inputs, ret = getsignature(self.rtyper, impl) + exmpl = impl or attrdef.s_value.prebuiltinstances.keys()[0] + f, inputs, ret = getsignature(self.rtyper, exmpl) M = ootype.Meth([r.lowleveltype for r in inputs[1:]], ret.lowleveltype) - m = ootype.meth(M, _name=mangled, _callable=impl, - graph=f.graph) + if impl: + m = ootype.meth(M, _name=mangled, _callable=impl, + graph=f.graph) + else: + m = None methods[mangled] = m allmethods[mangled] = True else: Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Thu Oct 20 11:47:18 2005 @@ -491,3 +491,23 @@ return e.attr() res = interpret(f, []) assert res == 42 + +def test_abstract_base_method(): + class A(object): + pass + class B(A): + def f(self): + return 2 + class C(A): + def f(self): + return 3 + def f(flag): + if flag: + x = B() + else: + x = C() + return x.f() + res = interpret(f, [True]) + assert res == 2 + res = interpret(f, [False]) + assert res == 3 From arigo at codespeak.net Thu Oct 20 11:55:33 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 11:55:33 +0200 (CEST) Subject: [pypy-svn] r18788 - in pypy/dist/pypy/rpython: . ootypesystem Message-ID: <20051020095533.4BCA327B5D@code1.codespeak.net> Author: arigo Date: Thu Oct 20 11:55:32 2005 New Revision: 18788 Modified: pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/ootypesystem/rclass.py Log: Can't use None for abstract methods, it makes typeOf() unhappy and there is no signature. Use a _meth with no _callable, no graph, and abstract=True. (thanks pedronis) Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Thu Oct 20 11:55:32 2005 @@ -646,6 +646,8 @@ bm = getattr(inst, message) m = bm.meth m._checkargs(args) + if getattr(m, 'abstract', False): + raise RuntimeError("calling abstract method %r" % (m,)) return self.op_direct_call(m, inst, *args) def op_ooupcast(self, INST, inst): Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Thu Oct 20 11:55:32 2005 @@ -73,11 +73,10 @@ # _add_fields adds *descriptions* of fields. This is obvious # if you are in the right state of mind (swiss?), but # certainly not necessarily if not. - # NB. a None method is a purely abstract one. for name, method in methods.iteritems(): if self._has_field(name): raise TypeError("Can't add method %r: field already exists" % name) - if method is not None and not isinstance(typeOf(method), Meth): + if not isinstance(typeOf(method), Meth): raise TypeError("added methods must be _meths, not %s" % type(defn)) self._methods.update(methods) Modified: pypy/dist/pypy/rpython/ootypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/rclass.py Thu Oct 20 11:55:32 2005 @@ -158,7 +158,7 @@ m = ootype.meth(M, _name=mangled, _callable=impl, graph=f.graph) else: - m = None + m = ootype.meth(M, _name=mangled, abstract=True) methods[mangled] = m allmethods[mangled] = True else: From arigo at codespeak.net Thu Oct 20 13:03:44 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 13:03:44 +0200 (CEST) Subject: [pypy-svn] r18790 - pypy/dist/pypy/objspace/flow Message-ID: <20051020110344.543E727B5D@code1.codespeak.net> Author: arigo Date: Thu Oct 20 13:03:43 2005 New Revision: 18790 Modified: pypy/dist/pypy/objspace/flow/objspace.py Log: comment. Modified: pypy/dist/pypy/objspace/flow/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/flow/objspace.py (original) +++ pypy/dist/pypy/objspace/flow/objspace.py Thu Oct 20 13:03:43 2005 @@ -493,7 +493,7 @@ x = X() x_cell, = (lambda: x).func_closure x_cell == c - return x.other + return x.other # crashes if the cell is actually empty def make_op(name, symbol, arity, specialnames): if hasattr(FlowObjSpace, name): From arigo at codespeak.net Thu Oct 20 13:18:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 13:18:27 +0200 (CEST) Subject: [pypy-svn] r18791 - in pypy/dist/pypy/rpython: . module module/test Message-ID: <20051020111827.63CE327B5D@code1.codespeak.net> Author: arigo Date: Thu Oct 20 13:18:26 2005 New Revision: 18791 Modified: pypy/dist/pypy/rpython/annlowlevel.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/rpython/module/support.py pypy/dist/pypy/rpython/module/test/test_ll_os.py pypy/dist/pypy/rpython/ros.py pypy/dist/pypy/rpython/rspecialcase.py Log: * RPythonic helpers to implement os.listdir(): the C-ish functions ros.opendir(), readdir(), closedir(). * support for external types that are externally-managed pointers (used here for the DIR* pointer). This means that closedir() must be called explicitely from RPython! Modified: pypy/dist/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/dist/pypy/rpython/annlowlevel.py (original) +++ pypy/dist/pypy/rpython/annlowlevel.py Thu Oct 20 13:18:26 2005 @@ -80,6 +80,11 @@ exttypeinfo = s_opaqueptr.ll_ptrtype.TO._exttypeinfo return annmodel.SomeExternalObject(exttypeinfo.typ) + def override__to_opaque_object(pol, s_value): + assert isinstance(s_value, annmodel.SomeExternalObject) + exttypeinfo = extfunctable.typetable[s_value.knowntype] + return annmodel.SomePtr(lltype.Ptr(exttypeinfo.get_lltype())) + def annotate_lowlevel_helper(annotator, ll_function, args_s): saved = annotator.policy, annotator.added_blocks Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Thu Oct 20 13:18:26 2005 @@ -28,11 +28,12 @@ class ExtTypeInfo: - def __init__(self, typ, tag, methods): + def __init__(self, typ, tag, methods, needs_container=True): self.typ = typ self.tag = tag self._TYPE = None self.methods = methods # {'name': ExtFuncInfo()} + self.needs_container = needs_container def get_annotation(self, methodname): return self.methods[methodname].annotation @@ -51,8 +52,11 @@ from pypy.rpython import lltype OPAQUE = lltype.OpaqueType(self.tag) OPAQUE._exttypeinfo = self - STRUCT = lltype.GcStruct(self.tag, ('obj', OPAQUE)) - self._TYPE = STRUCT + if self.needs_container: + STRUCT = lltype.GcStruct(self.tag, ('obj', OPAQUE)) + self._TYPE = STRUCT + else: + self._TYPE = OPAQUE return self._TYPE @@ -87,7 +91,7 @@ return info typetable = {} -def declaretype(typ, tag, **methodsdecl): +def declaretype1(typ, tag, methodsdecl, needs_container): assert isinstance(typ, type) methods = {} for name, args in methodsdecl.items(): @@ -99,12 +103,18 @@ else: func = None # failed (typical for old-style C types), ignore it methods[name] = declare(func, *args) - info = ExtTypeInfo(typ, tag, methods) + info = ExtTypeInfo(typ, tag, methods, needs_container) typetable[typ] = info for callback in table_callbacks: callback() return info +def declaretype(typ, tag, **methodsdecl): + return declaretype1(typ, tag, methodsdecl, needs_container=True) + +def declareptrtype(typ, tag, **methodsdecl): + return declaretype1(typ, tag, methodsdecl, needs_container=False) + # _____________________________________________________________ @@ -204,6 +214,10 @@ from pypy.rpython import ros declare(ros.putenv, noneannotation, 'll_os/putenv') declare(ros.environ, strnullannotation, 'll_os/environ') +declare(ros.opendir, ros.DIR, 'll_os/opendir') +declareptrtype(ros.DIR, "DIR", + readdir = (strnullannotation, 'll_os/readdir'), + closedir = (noneannotation, 'll_os/closedir')) # ___________________________________________________________ # stackless 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 Oct 20 13:18:26 2005 @@ -17,6 +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.module.support import to_opaque_object, from_opaque_object from pypy.rpython import ros def ll_os_open(fname, flag, mode): @@ -147,3 +148,22 @@ def ll_os_environ(idx): return ros.environ(idx) ll_os_environ.suggested_primitive = True + +# ____________________________________________________________ +# opendir/readdir + +def ll_os_opendir(dirname): + dir = ros.opendir(from_rstr(dirname)) + return to_opaque_object(dir) +ll_os_opendir.suggested_primitive = True + +def ll_os_readdir(opaquedir): + dir = from_opaque_object(opaquedir) + nextentry = dir.readdir() + return to_rstr(nextentry) +ll_os_readdir.suggested_primitive = True + +def ll_os_closedir(opaquedir): + dir = from_opaque_object(opaquedir) + dir.closedir() +ll_os_closedir.suggested_primitive = True Modified: pypy/dist/pypy/rpython/module/support.py ============================================================================== --- pypy/dist/pypy/rpython/module/support.py (original) +++ pypy/dist/pypy/rpython/module/support.py Thu Oct 20 13:18:26 2005 @@ -6,13 +6,18 @@ # utility conversion functions def to_rstr(s): + if s is None: + return lltype.nullptr(STR) p = malloc(STR, len(s)) for i in range(len(s)): p.chars[i] = s[i] return p def from_rstr(rs): - return ''.join([rs.chars[i] for i in range(len(rs.chars))]) + if not rs: # null pointer + return None + else: + return ''.join([rs.chars[i] for i in range(len(rs.chars))]) def ll_strcpy(dstchars, srcchars, n): i = 0 @@ -29,3 +34,10 @@ "NOT_RPYTHON" return opaqueptr._obj.externalobj from_opaque_object._annspecialcase_ = "override:from_opaque_object" + +def to_opaque_object(value): + "NOT_RPYTHON" + exttypeinfo = extfunctable.typetable[value.__class__] + return lltype.opaqueptr(exttypeinfo.get_lltype(), 'opaque', + externalobj=value) +to_opaque_object._annspecialcase_ = "override:to_opaque_object" 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 Thu Oct 20 13:18:26 2005 @@ -80,3 +80,24 @@ assert res chan.close() +def test_opendir_readdir(): + dirname = str(udir) + rsdirname = to_rstr(dirname) + result = [] + DIR = ll_os_opendir(rsdirname) + try: + while True: + nextentry = ll_os_readdir(DIR) + if not nextentry: # null pointer check + break + result.append(from_rstr(nextentry)) + finally: + ll_os_closedir(DIR) + assert '.' in result + assert '..' in result + result.remove('.') + result.remove('..') + result.sort() + compared_with = os.listdir(dirname) + compared_with.sort() + assert result == compared_with Modified: pypy/dist/pypy/rpython/ros.py ============================================================================== --- pypy/dist/pypy/rpython/ros.py (original) +++ pypy/dist/pypy/rpython/ros.py Thu Oct 20 13:18:26 2005 @@ -15,3 +15,23 @@ # we simulate the environ list if idx < len(_initial_items): return '%s=%s' % _initial_items[idx] + + +class DIR(object): + # a simulated DIR structure from C, i.e. a directory opened by + # opendir() from which we can enumerate the entries with readdir(). + # Like readdir(), this version does not hide the '.' and '..' entries. + def __init__(self, dirname): + self._entries = iter(['.', '..'] + os.listdir(dirname)) + + def readdir(self): + try: + return self._entries.next() + except StopIteration: + return None + + def closedir(self): + pass + +def opendir(dirname): + return DIR(dirname) Modified: pypy/dist/pypy/rpython/rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/rspecialcase.py (original) +++ pypy/dist/pypy/rpython/rspecialcase.py Thu Oct 20 13:18:26 2005 @@ -40,3 +40,7 @@ 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) + +def rtype_override_to_opaque_object(hop, clsdef): + return hop.genop('to_opaque_object_should_never_be_seen_by_the_backend', + [], resulttype=hop.r_result) From arigo at codespeak.net Thu Oct 20 13:26:07 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 13:26:07 +0200 (CEST) Subject: [pypy-svn] r18792 - in pypy/dist/pypy/translator/c: . src test Message-ID: <20051020112607.DF2E127B5D@code1.codespeak.net> Author: arigo Date: Thu Oct 20 13:26:07 2005 New Revision: 18792 Modified: 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: C version of opendir/readdir/closedir. Hopefully this works on Windows as well -- looking at the CPython posixmodule.c, there is a chance that modern Windows have these functions as well, but I can't tell for sure. Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Thu Oct 20 13:26:07 2005 @@ -32,6 +32,9 @@ 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_os .ll_os_opendir: 'LL_os_opendir', + ll_os .ll_os_readdir: 'LL_os_readdir', + ll_os .ll_os_closedir:'LL_os_closedir', 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 Oct 20 13:26:07 2005 @@ -58,6 +58,9 @@ void LL_os_putenv(RPyString * name_eq_value); void LL_os_unsetenv(RPyString * name); RPyString* LL_os_environ(int idx); +struct RPyOpaque_DIR *LL_os_opendir(RPyString *dirname); +RPyString *LL_os_readdir(struct RPyOpaque_DIR *dir); +void LL_os_closedir(struct RPyOpaque_DIR *dir); /* implementations */ @@ -272,4 +275,55 @@ } return rs; } + +/******************** opendir/readdir/closedir ********************/ + +#ifdef HAVE_DIRENT_H +#include +#define NAMLEN(dirent) strlen((dirent)->d_name) +#else +#if defined(__WATCOMC__) && !defined(__QNX__) +#include +#define NAMLEN(dirent) strlen((dirent)->d_name) +#else +#define dirent direct +#define NAMLEN(dirent) (dirent)->d_namlen +#endif +#ifdef HAVE_SYS_NDIR_H +#include +#endif +#ifdef HAVE_SYS_DIR_H +#include +#endif +#ifdef HAVE_NDIR_H +#include +#endif +#endif + +struct RPyOpaque_DIR *LL_os_opendir(RPyString *dirname) +{ + DIR *dir = opendir(RPyString_AsString(dirname)); + if (dir == NULL) + RPYTHON_RAISE_OSERROR(errno); + return (struct RPyOpaque_DIR *) dir; +} + +RPyString *LL_os_readdir(struct RPyOpaque_DIR *dir) +{ + struct dirent *d; + errno = 0; + d = readdir((DIR *) dir); + if (d != NULL) + return RPyString_FromString(d->d_name); + if (errno) + RPYTHON_RAISE_OSERROR(errno); + return NULL; +} + +void LL_os_closedir(struct RPyOpaque_DIR *dir) +{ + if (closedir((DIR *) dir) < 0) + RPYTHON_RAISE_OSERROR(errno); +} + #endif /* PYPY_NOT_MAIN_FILE */ 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 Oct 20 13:26:07 2005 @@ -499,6 +499,31 @@ f() assert _real_getenv('ABCDEF') is None +def test_opendir_readdir(): + def mylistdir(s): + result = [] + dir = ros.opendir(s) + try: + while True: + nextentry = dir.readdir() + if nextentry is None: + break + result.append(nextentry) + finally: + dir.closedir() + return '\x00'.join(result) + func = compile(mylistdir, [str]) + result = func(str(udir)) + result = result.split('\x00') + assert '.' in result + assert '..' in result + result.remove('.') + result.remove('..') + result.sort() + compared_with = os.listdir(str(udir)) + compared_with.sort() + assert result == compared_with + def test_socket(): import _socket import pypy.module._socket.rpython.exttable # for declare()/declaretype() From bea at codespeak.net Thu Oct 20 14:21:03 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Thu, 20 Oct 2005 14:21:03 +0200 (CEST) Subject: [pypy-svn] r18795 - pypy/extradoc/planning Message-ID: <20051020122103.698C127B69@code1.codespeak.net> Author: bea Date: Thu Oct 20 14:21:02 2005 New Revision: 18795 Modified: pypy/extradoc/planning/phase2_projectactivities.txt Log: typos Modified: pypy/extradoc/planning/phase2_projectactivities.txt ============================================================================== --- pypy/extradoc/planning/phase2_projectactivities.txt (original) +++ pypy/extradoc/planning/phase2_projectactivities.txt Thu Oct 20 14:21:02 2005 @@ -142,7 +142,7 @@ Submission date: ? -EU-related Workpackage planning planning phase 2 +EU-related Workpackage planning phase 2 ------------------------------------------------- - WP09 and WP10 done and coordinated by logilab/dfki @@ -177,7 +177,7 @@ DO1.1 Create QA plan for the project Primary/Secondary: Bea/Holger -Completion date: 16th Oct 2005 +Completion date: 21th Oct 2005 D04.1 Partial Python Impl: Primary/Secondary: Jacob / Christian From cfbolz at codespeak.net Thu Oct 20 15:28:33 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Oct 2005 15:28:33 +0200 (CEST) Subject: [pypy-svn] r18796 - pypy/extradoc/minute Message-ID: <20051020132833.17ADA27B55@code1.codespeak.net> Author: cfbolz Date: Thu Oct 20 15:28:31 2005 New Revision: 18796 Added: pypy/extradoc/minute/pypy-sync-10-20-2005.txt Log: minutes for todays pypy-sync meeting. Added: pypy/extradoc/minute/pypy-sync-10-20-2005.txt ============================================================================== --- (empty file) +++ pypy/extradoc/minute/pypy-sync-10-20-2005.txt Thu Oct 20 15:28:31 2005 @@ -0,0 +1,308 @@ +============================================= +pypy-sync developer meeting 20th October +============================================= + +Time & location: 1pm (30 minutes) at #pypy-sync + +Attendees:: + + Samuele Pedroni + Armin Rigo + Anders Chrigstr?m + Christian Tismer + Holger Krekel + Eric van Riet Paap + Michael Hudson + Carl Friedrich Bolz + Bert Freudenberg + Adrien di Mascio (late) + + +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 blockers + +Topics of the week +=================== + + +Status update and next steps +----------------------------- + +ootypesystem +++++++++++++ + +Armin reports that classes/instance support in the rtyper for ootypes seems +reasonably complete now: class attributes, abstract base methods, function +pointers stored on instances seem to work. Missing are all other high level +types like strings, lists, tuples, dicts, etc. Samuele notes that there might +still be problems with obscure prebuilt constants. Bert intends to work on +the squeak backend and Armin tries to help him as far as his work on reports +permit that. Holger notes that Impara's work should be more focused on +evaluating the possibilities how to integrate pypy and squeak to which Bert +agrees. + +stackless integration ++++++++++++++++++++++ + +Armin points at the discussion that took place on PyPy-dev: + +http://codespeak.net/pipermail/pypy-dev/2005q4/002519.html + +and also notes that some more discussion might be needed. The current state of +the app-level stackless module is described at: + +http://codespeak.net/svn/pypy/extradoc/sprintinfo/paris/stackless-discussion.txt + +Christian is working on reducing the overhead of stackless. There was some +discussion about the question whether stackless should be mentioned as +implemented in the current reports already. Holger and Carl Friedrich are +opposed to this idea since there will be a lot more reports coming. +Armin and Christian were in favor of writing about it. Some further discussion +is needed about this. + + +l3interpreter ++++++++++++++ + +Carl Friedrich describes the current the of the l3interpreter: the +basic model is in place, for now only some operations with integers work. +There is some code that can convert low level to l3 graphs but it is far +from complete. Everybody agreed that nobody will work on the l3interpreter +until should not be worked on until the reports are finished. + + +compiler +++++++++ + +Adrien thinks that compiler seems more or less stable now, although there are +still some bugs found every now and then. It was agreed upon that nobody will +work on it for a while. + +javascript backend +++++++++++++++++++ + +Eric describes the current state of the JS backend: it passes around 50% +of the LLVM tests. The work on the JS backend is simpler because GC and +exception handling can be handed down to the underlying JS interpreter. +Eric will give a lightning talk on OSCON in Amsterdam and ask for feedback +there. + +Next pypy-sync meeting +------------------------------- + +Scheduled for next Thursday, Oct. 27th 13.00h CET, conducted by Carl Friedrich + + +Closing +------------------ + +Carl Friedrich closes the meeting in time. + +.. _`IRC-Log`: + +Log: +------------ +Here is the full IRC log:: + + **** BEGIN LOGGING AT Thu Oct 20 12:27:08 2005 + + Oct 20 12:27:08 * Now talking on #pypy-sync + Oct 20 12:51:06 * hpk (n=holger_k at adsl-218-181-192-81.adsl2.iam.net.ma) has joined #pypy-sync + Oct 20 12:51:17 * pedronis (n=Samuele_ at c-3c8b70d5.022-54-67626719.cust.bredbandsbolaget.se) has joined #pypy-sync + Oct 20 12:51:57 * stakkars (n=tismer at ip-80-226-228-223.vodafone-net.de) has joined #pypy-sync + Oct 20 12:58:57 * mwh (n=mwh at 134.99.112.244) has joined #pypy-sync + Oct 20 13:00:02 cfbolz hi all! it 1pm on my clock now, shall we start? + Oct 20 13:00:20 stakkars DONE: more on source ordering, stackless experiments + Oct 20 13:00:21 stakkars NEXT: finishing this, continue on spackless stuff + Oct 20 13:00:21 stakkars BLOCK: None + Oct 20 13:00:43 mwh last: form filling, recovering from sprint, playing with gcc optimisations + Oct 20 13:00:43 mwh next: reports, not sure what else + Oct 20 13:00:43 mwh blockers: german bureaucracy + Oct 20 13:00:48 hpk LAST: paris sprint, eu issues/background organisation, codespeak issues NEXT: getting eric on board, some codespeak stuff, marocco BLOCKERS: mixed connectivity + Oct 20 13:01:04 * arigo (n=arigo at 134.99.112.244) has joined #pypy-sync + Oct 20 13:01:10 arigo hi all + Oct 20 13:01:10 cfbolz LAST: sprinting, working on statistics gathering and code coverage + Oct 20 13:01:10 cfbolz NEXT: more statistics, code coverage, reports + Oct 20 13:01:10 cfbolz BLOCKERS: too many tasks :-) + Oct 20 13:01:25 pedronis LAST: sprint; looking into packing 0.6 test results, D04.4; annotation for fixed-size list support + Oct 20 13:01:27 pedronis NEXT: reports, ... + Oct 20 13:01:28 pedronis BLOCKERS: - + Oct 20 13:01:43 arigo DONE: ootyper (classes/instances roughly complete now); some continuation + Oct 20 13:01:43 arigo experiments; more pypy-c debugging (it still doesn't run py.py) + Oct 20 13:01:43 arigo NEXT: reports D05.1 and D05.4 :-/ + Oct 20 13:01:43 arigo BLOCKERS: - + Oct 20 13:02:27 cfbolz erics lines: + Oct 20 13:02:31 cfbolz Last: exception handling in Javascript + Oct 20 13:02:31 cfbolz Next: genjs + Oct 20 13:02:31 cfbolz Blockers: - + Oct 20 13:02:44 cfbolz arre? + Oct 20 13:03:25 * bertf (n=bert at pD951499A.dip0.t-ipconnect.de) has joined #pypy-sync + Oct 20 13:03:35 * ericvrp2 (n=eric at 10-81-event-swisscomeurospot.infopact.nl) has joined #pypy-sync + Oct 20 13:03:42 cfbolz hi bert! want to post your acitvity report? + Oct 20 13:03:48 cfbolz hi eric! I just posted your lines + Oct 20 13:03:49 stakkars hi Bert, thanks for the wire + Oct 20 13:03:56 ericvrp2 'kay + Oct 20 13:04:17 bertf activities - recovering from sprint + Oct 20 13:05:11 cfbolz there don't seem to be blockers that can be resolved + Oct 20 13:05:20 cfbolz let's proceed to the regular topics + Oct 20 13:05:24 cfbolz Status update and next steps + Oct 20 13:05:28 cfbolz ootypessytem + Oct 20 13:05:51 cfbolz can somebody give an update about the status there? + Oct 20 13:06:29 arigo yes + Oct 20 13:06:40 arigo the classes/instances support seem reasonably complete now + Oct 20 13:07:01 arigo class attributes, abstract base methods, function pointers stored on instances, etc. + Oct 20 13:07:12 arigo I basically copied rclass.py from lltype one test at a time + Oct 20 13:07:29 bertf nice :) + Oct 20 13:07:38 arigo so what's missing now are all other high-level types: strings, lists, tuples, dicts, etc. + Oct 20 13:07:50 arigo I guess we need to discuss more before we start that + Oct 20 13:08:00 pedronis and I suppose passing more obscure rpbc stuff + Oct 20 13:08:07 cfbolz arigo: indeed. later on #pypy? + Oct 20 13:08:11 arigo sure + Oct 20 13:08:30 cfbolz who is going to work on this the next weeks? + Oct 20 13:08:31 arigo pedronis: yes, though I think half of the obscure stuff will work magically :-) + Oct 20 13:08:46 pedronis yes, there's a chance + Oct 20 13:08:48 arre Sorry for joining late. + Oct 20 13:08:53 * stakkars is on a modem line. following on #pypy will be too expensive,today + Oct 20 13:09:26 arigo from now on, a lot of the hard stuff in rdict.py&co will be easy and pushed to the back-end (i.e. Bert :-) + Oct 20 13:09:39 bertf fine with me ... + Oct 20 13:09:43 cfbolz ok + Oct 20 13:10:03 arigo I can continue to help anyway (reports reports reports) + Oct 20 13:10:22 cfbolz yes + Oct 20 13:10:25 cfbolz next topic? + Oct 20 13:10:29 cfbolz stackless integration + Oct 20 13:10:29 cfbolz --------------------- + Oct 20 13:10:33 cfbolz status? + Oct 20 13:10:40 arre cfboltz: Want my lines? + Oct 20 13:10:56 cfbolz arre: ok + Oct 20 13:11:08 arre PREV: preparing data for reports, catching up on work done during sprint + Oct 20 13:11:09 arre NEXT: Help my parents move (No PyPy work) + Oct 20 13:11:09 arre BLOCKERS: None + Oct 20 13:11:23 cfbolz thanks + Oct 20 13:11:25 arigo stackless integration: more discussion needed with Christian + Oct 20 13:11:45 * hpk just sidenotes that the focus of impara should nevertheless probably be on an evaluation/laying out of the approaches of integrating squeak with pypy + Oct 20 13:11:47 stakkars well, the current plan looks fine. + Oct 20 13:12:15 stakkars I'm also looking into ways to reduce the overhead. + Oct 20 13:12:30 * bertf nods + Oct 20 13:13:09 * stakkars can discuss in the evening a bit + Oct 20 13:13:19 cfbolz current plan is the discussion that took on on pypy-dev? + Oct 20 13:13:26 arigo yes + Oct 20 13:13:51 cfbolz ok. christian, are you going to work on that? + Oct 20 13:14:17 stakkars sure. And I'd like to help with reporting (preferredly writing towads stackless stuff but well) + Oct 20 13:14:30 cfbolz great + Oct 20 13:14:57 hpk i think stackless is not the focus on phase 1 reports, but it can be hinted at when talking about flexibility + Oct 20 13:15:05 stakkars after a break and some home trouble, I'm about to finish code ordering (convergence problem) and sqitch to stackless then + Oct 20 13:15:12 * adim (n=adim at logilab.net2.nerim.net) has joined #pypy-sync + Oct 20 13:15:13 arigo hpk: D05.3 should talk about stackless in some details + Oct 20 13:15:17 stakkars ah - oh + Oct 20 13:15:25 adim Hi everyone (sorry for being late) + Oct 20 13:15:36 hpk (claiming that the architecture provides enoug leeway for stackless as if we hadn't tried it already, so we can be bold :-) + Oct 20 13:15:41 cfbolz but this needs to be carefully done, since after all there are other stackless reports later + Oct 20 13:16:10 cfbolz so we probably don't want to give it all away already + Oct 20 13:16:13 hpk it should just be more or less bold claims / statements about the architecture for phase 1 IMO + Oct 20 13:16:19 stakkars reporting about the current achievement would make sense,although I don't know whether Armin wants to do it + Oct 20 13:16:51 arigo maybe we can report about what we got at the end of the sprint + Oct 20 13:16:53 hpk no, i do think that we have to think about correct timing, our reports will always lack behind + Oct 20 13:17:11 stakkars arigo: that's what I meant + Oct 20 13:17:11 hpk we have 40 reports to go (or some such) + Oct 20 13:17:22 arigo stakkars: ok + Oct 20 13:17:32 hpk arigo, stakkars : but i disagree + Oct 20 13:17:36 arigo hpk: I see the point + Oct 20 13:18:11 cfbolz let's defer this to #pypy, I'd say + Oct 20 13:18:15 cfbolz l3interpreter + Oct 20 13:18:15 cfbolz ------------- + Oct 20 13:18:28 cfbolz I can say something about the status + Oct 20 13:18:43 cfbolz the basic model is in place, it ignores everything except integers for now + Oct 20 13:18:43 hpk cfbolz: defering without refering to persons seems difficult, but well + Oct 20 13:19:20 cfbolz hpk: point taken + Oct 20 13:19:59 cfbolz to l3interpreter there is some code that converts l2 to l3 but it can't do very much yet + Oct 20 13:19:59 mwh what types will the l3interpreter need to know about eventually? + Oct 20 13:20:11 hpk the question is (IMO) if we want to work much on l3interpreter in the next weeks + Oct 20 13:20:21 cfbolz probably rather not + Oct 20 13:20:56 cfbolz too much work on reports to do + Oct 20 13:21:11 mwh indeed + Oct 20 13:21:39 cfbolz so I'd say I'll try to write a bit about the plans we had at the sprint and put it to sleep afterwards + Oct 20 13:22:03 hpk yip, i think so as well + Oct 20 13:22:15 cfbolz ok then + Oct 20 13:22:16 cfbolz compiler + Oct 20 13:22:16 cfbolz -------- + Oct 20 13:22:24 cfbolz could anybody tell what the status there is? + Oct 20 13:22:38 mwh well, we found another crazy bug last night + Oct 20 13:22:53 adim mwh: ah ? + Oct 20 13:22:58 mwh armin fixed it somewhat + Oct 20 13:23:05 hpk sorry, i have to ask: does everybody else think it's ok to postpone l3interpreter until - say - december? + Oct 20 13:23:26 mwh adim: from Lib/compiler, to do with __name mangling + Oct 20 13:23:37 arigo hpk: no, I'd only say until we are done with the bunch of thereports + Oct 20 13:23:43 stakkars yes. in effect this would continue at the next sprint, then. + Oct 20 13:23:53 cfbolz arigo: which will probably nearly be december :-) + Oct 20 13:23:58 arigo ok ok :-) + Oct 20 13:24:02 hpk arigo: ok, this will be aerly december, i am afraid, but we'll see + Oct 20 13:24:09 adim cfbolz: for the compiler, I would say that we can consider it as finished since failing compliancy tests are note compiler-related bugs + Oct 20 13:24:27 adim but it doesn't guarantee that there's no bug left + Oct 20 13:24:43 hpk surely not + Oct 20 13:24:55 cfbolz so will anybody work on it? + Oct 20 13:25:09 pedronis arigo, hpk: I see, the important thing is that when we restart we have a short discussion on what next, if we manage before december + Oct 20 13:25:10 arigo the bugs are not known yet :-) + Oct 20 13:25:13 adim I don't really think so. + Oct 20 13:25:16 mwh as bugs are found, surely + Oct 20 13:25:18 adim :) + Oct 20 13:25:28 cfbolz ok, makes sense for everybody? + Oct 20 13:25:39 hpk makes sense to consider it finished for now, yes + Oct 20 13:25:43 hpk (to me) + Oct 20 13:25:55 cfbolz to me as well + Oct 20 13:26:15 arigo yes + Oct 20 13:26:21 stakkars 'k + Oct 20 13:26:34 mwh is this some kind of vote? :) + Oct 20 13:26:37 cfbolz yes + Oct 20 13:26:39 cfbolz :-) + Oct 20 13:26:41 cfbolz ok then + Oct 20 13:26:42 * mwh says "aye" too + Oct 20 13:26:45 cfbolz javascript backend + Oct 20 13:26:45 cfbolz ------------------ + Oct 20 13:26:50 arre Aye. + Oct 20 13:27:03 cfbolz ericvrp2? + Oct 20 13:27:03 ericvrp2 genjs is passing about 50% of the (llvm) unittests. + Oct 20 13:27:04 ericvrp2 The resulting javascript code is run with a standlone js interpreter called Spidermonkey. + Oct 20 13:27:06 hpk mwh: we use to answer questions like this from the moderator :like "is everybody ..." :-) + Oct 20 13:27:06 ericvrp2 Actual testing in browsers is being worked on by Guido Wesdorp. + Oct 20 13:27:09 ericvrp2 The code looks very similar but simpler that the C/LLVM code. + Oct 20 13:27:12 ericvrp2 This is mostly because I can use JS' garbage collection and excption handling. + Oct 20 13:27:17 ericvrp2 I am here now at euro OSCON in Amsterdam to give a 5 minute lightning talk about it + Oct 20 13:27:18 ericvrp2 and my question to the audience will be to come up with use-cases. + Oct 20 13:27:33 cfbolz :-) + Oct 20 13:27:38 hpk :-) + Oct 20 13:27:51 adim :) + Oct 20 13:27:53 * ericvrp2 blurb + Oct 20 13:28:05 hpk does spidermonkey also provide some dom-simulation or so? + Oct 20 13:28:12 * hpk notices that time is getting short + Oct 20 13:28:20 ericvrp2 I don't think so + Oct 20 13:28:22 cfbolz indeed, less than two min left + Oct 20 13:28:36 mwh anything else? + Oct 20 13:28:53 pedronis should we think to do new a release? + Oct 20 13:28:56 mwh i probably won't sign my contract on this visit to duesseldorf :( + Oct 20 13:29:00 cfbolz :-( + Oct 20 13:29:03 hpk pedronis: next pypy-sync meeting? + Oct 20 13:29:07 cfbolz indeed + Oct 20 13:29:09 hpk mwh: buah + Oct 20 13:29:29 cfbolz anybody opposed to close the meeting? + Oct 20 13:29:36 hpk nope + Oct 20 13:29:58 stakkars bye + Oct 20 13:30:01 ericvrp2 bye + Oct 20 13:30:04 adim bye + Oct 20 13:30:05 arigo bye + Oct 20 13:30:17 bertf bye + Oct 20 13:30:27 cfbolz see you all next week! + Oct 20 13:30:42 * adim (n=adim at logilab.net2.nerim.net) has left #pypy-sync + Oct 20 13:30:57 * mwh (n=mwh at 134.99.112.244) has left #pypy-sync + Oct 20 13:31:09 * ericvrp2 has quit ("leaving") + Oct 20 13:31:12 * arre (i=ba81f155 at 1-1-5-33a.gfa.gbg.bostream.se) has left #pypy-sync + Oct 20 13:31:20 hpk bye + Oct 20 13:31:30 * bertf (n=bert at pD951499A.dip0.t-ipconnect.de) has left #pypy-sync + Oct 20 13:32:08 * arigo (n=arigo at 134.99.112.244) has left #pypy-sync + **** ENDING LOGGING AT Thu Oct 20 13:33:51 2005 + From arigo at codespeak.net Thu Oct 20 16:48:54 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 16:48:54 +0200 (CEST) Subject: [pypy-svn] r18798 - in pypy/dist/pypy/module/posix: . test Message-ID: <20051020144854.AFC2827B70@code1.codespeak.net> Author: arigo Date: Thu Oct 20 16:48:53 2005 New Revision: 18798 Modified: pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/module/posix/interp_posix.py pypy/dist/pypy/module/posix/test/test_posix2.py Log: os.listdir() at app-level. Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Thu Oct 20 16:48:53 2005 @@ -35,7 +35,8 @@ 'chdir' : 'interp_posix.chdir', 'mkdir' : 'interp_posix.mkdir', 'rmdir' : 'interp_posix.rmdir', - 'environ' : 'interp_posix.get(space).w_environ' + 'environ' : 'interp_posix.get(space).w_environ', + 'listdir' : 'interp_posix.listdir', } 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 Oct 20 16:48:53 2005 @@ -232,3 +232,24 @@ # old value was still accessible until then. del get(space).posix_putenv_garbage[name] unsetenv.unwrap_spec = [ObjSpace, str] + + +def enumeratedir(space, dir): + result = [] + while True: + nextentry = dir.readdir() + if nextentry is None: + break + if nextentry not in ('.' , '..'): + result.append(space.wrap(nextentry)) + return space.newlist(result) + +def listdir(space, dirname): + dir = ros.opendir(dirname) + try: + # sub-function call to make sure that 'try:finally:' will catch + # everything including MemoryErrors + return enumeratedir(space, dir) + finally: + dir.closedir() +listdir.unwrap_spec = [ObjSpace, str] Modified: pypy/dist/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/dist/pypy/module/posix/test/test_posix2.py (original) +++ pypy/dist/pypy/module/posix/test/test_posix2.py Thu Oct 20 16:48:53 2005 @@ -6,12 +6,18 @@ mod.space = StdObjSpace(usemodules=['posix']) mod.path = udir.join('posixtestfile.txt') mod.path.write("this is a test") + pdir = udir.ensure('posixtestdir', dir=True) + pdir.join('file1').write("test1") + pdir.join('file2').write("test2") + pdir.join('another_longer_file_name').write("test3") + mod.pdir = pdir 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)) + cls.w_pdir = space.wrap(str(pdir)) def test_posix_is_pypy_s(self): assert self.posix.__file__ @@ -75,6 +81,15 @@ else: raise "did not raise" + def test_listdir(self): + pdir = self.pdir + posix = self.posix + result = posix.listdir(pdir) + result.sort() + assert result == ['another_longer_file_name', + 'file1', + 'file2'] + class AppTestEnvironment(object): def setup_class(cls): cls.space = space From arigo at codespeak.net Thu Oct 20 16:49:13 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 16:49:13 +0200 (CEST) Subject: [pypy-svn] r18799 - in pypy/dist/pypy/translator: . c java pickle Message-ID: <20051020144913.1D13D27B70@code1.codespeak.net> Author: arigo Date: Thu Oct 20 16:49:12 2005 New Revision: 18799 Modified: pypy/dist/pypy/translator/c/pyobj.py pypy/dist/pypy/translator/geninterplevel.py pypy/dist/pypy/translator/java/genjava.py pypy/dist/pypy/translator/pickle/genpickle.py Log: of CPython is called in PyPy. Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Thu Oct 20 16:49:12 2005 @@ -200,6 +200,8 @@ func, ob, typ)) return name + nameof_method = nameof_instancemethod # when run on top of PyPy + def should_translate_attr(self, pbc, attr): ann = self.translator.annotator if ann is None or isinstance(pbc, ObjSpace): Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Thu Oct 20 16:49:12 2005 @@ -628,6 +628,8 @@ '%s = space.getattr(%s, %s)' % (name, ob, funcname)) return name + nameof_method = nameof_instancemethod # when run on top of PyPy + def should_translate_attr(self, pbc, attr): ann = self.translator.annotator if ann is None: Modified: pypy/dist/pypy/translator/java/genjava.py ============================================================================== --- pypy/dist/pypy/translator/java/genjava.py (original) +++ pypy/dist/pypy/translator/java/genjava.py Thu Oct 20 16:49:12 2005 @@ -214,6 +214,8 @@ name, func, ob, typ)) return name + nameof_method = nameof_instancemethod # when run on top of PyPy + def should_translate_attr(self, pbc, attr): ann = self.translator.annotator if ann is None: Modified: pypy/dist/pypy/translator/pickle/genpickle.py ============================================================================== --- pypy/dist/pypy/translator/pickle/genpickle.py (original) +++ pypy/dist/pypy/translator/pickle/genpickle.py Thu Oct 20 16:49:12 2005 @@ -287,6 +287,8 @@ self.produce('%s = new.instancemethod(%s, %s, %s)' % ( name, func, ob, typ)) return name + + nameof_method = nameof_instancemethod # when run on top of PyPy def should_translate_attr(self, pbc, attr): ann = self.translator.annotator From arigo at codespeak.net Thu Oct 20 17:02:54 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Thu, 20 Oct 2005 17:02:54 +0200 (CEST) Subject: [pypy-svn] r18800 - pypy/extradoc/planning Message-ID: <20051020150254.6FA9827B6E@code1.codespeak.net> Author: arigo Date: Thu Oct 20 17:02:53 2005 New Revision: 18800 Modified: pypy/extradoc/planning/ (props changed) pypy/extradoc/planning/phase2_projectactivities.txt (contents, props changed) Log: fixeol Modified: pypy/extradoc/planning/phase2_projectactivities.txt ============================================================================== --- pypy/extradoc/planning/phase2_projectactivities.txt (original) +++ pypy/extradoc/planning/phase2_projectactivities.txt Thu Oct 20 17:02:53 2005 @@ -1,243 +1,243 @@ - -Rough preparation draft for saturday-afternoon 20051015 meeting Paris -------------------------------------------------------------- - -work group/pairing status ------------------------------- - -- ootypes / rtyper refactoring: - Boris reports: continued to refactor rypting into - non-ll specific and ll-specific parts. still a lot - of work to be done (currently you can specialize - an empty class with the oo-type system). - bert: squeak backend uses the oo-type system and - creates squeak class definitions. (oo-types are - built manually there at the moment). - -- socket module: - all the interface is wrapped/implemented at interpreter-level - and is reusing the underlying (cpython) socket module. There is - not translation/external function calls yet (which will introduce - platform issues). - -- numeric module: - started the basic Array type, you can construct such types that - contain floats or integers, and you can have efficient slices - (reusing the same underlying array). The base Array class - is not connected to storage, subclasses are (specific to floats/ints). - -- l3interpreter: - have a refined very-low-level flow graph model, and we can - pass in integers and do addition. also the l3intepreter - is translateable and passes tests. - -- compiler issues - ran the core compliancy tests (failing ones are mostly - due to missing weakref support). problem is that we - are having a mix of all slightly incorrect compiler - (or at least don't know if they/which are correct) - variations. It seems to make more sense to contribute the - whole astcompiler rather than trying to come up with patches - to the CPython version. - -- translation issues: - compliance tests start to run on pypy-c (test_builtin.py) - but there are likely more bugs/issues lurking. - christian is working on locality of references by - analysing flowgraphs. - -pypy technical task planning ----------------------------------- - -Identify tasks to be done in between sprints, start with -see paris-2005-possible-tasks.txt: - -- full compiler/parser integration - -- pypy-sync meetings should constantly track/amend/modify those - technical tasks and in general focus on technical issues - NOTE though: pypy-sync cannot focus too much on EU requirements - because it's a more open/community forum. - -- idea is to collect all larger tasks and bring plannings - to the pypy-sync meetings. Carl is going to do the next - pypy-sync meeting. Send plans/larger task plannings to - the moderators and don't wait until the moderator generates - the idea himself. - - -sprints & conferences -------------------------- - - next sprint: 5-11th December in Sweden (Change Maker?/G?tabergsgatan?) - Gborg. - - *(10 th January eu review workshop) - - *23-29th January: CS Dep. of the Palma de Mallorca University/CS Dep. of the Barcelona University - Bea check dates, Bruxelles/Louvain-la-neuve, Holger check dates), - - *27 Feb - 1st March: PyCon (24-26 Feb, 2006 Dallas, Texas, - postsprint, Michael/Holger, Armin, Christian, Bea), DEADLINE 30th - October - - *April Japan: (1) April 23 to April 29, (2) April 30 to May 5, contact: Yutaka Niibe, - National Institute of AIST, Japan (FSIJ) Akihabara, Tokyo (Bea), venue for 32 people. - (However, check with the EU). - - * (IBM workshop possibly end June, holger) - *6-9th (?) July: Europython Cern (3-5th July maybe in Leysin (Armin) Swizerland, - and the post-sprint at CERN, Michael/Holger) - - *21-27th August: University of Limerick/Ireland (Bea), maybe good possibility - to present pypy results to researchers. - - * 2-8th October: ? - * November: closure sprint - - Other possibilities: Romania, Switzerland (Leysin,Bern), Bristol, Uganda (Nkozi), bruxelles - -- Conference/y?talks planning: - - FIXED:27th October2005 PMI Chapter Sweden, methodology/PyPy talk in Link?ping (Bea) - - HALF-FIXED: 8th December 2005 Calibre/agile development workshop in - Bruxelles, Bea, Holger, Alastair attending (or maybe - just two persons). Bea coordinates (Alastair?). - - HALF-FIXED: CCC 27th-30th December Berlin (pypy technical talk accepted, - non-technical talk pending, may be unlikely, holger is keeping - contact) - - HALF-FIXED: 17th January 2006 (16th and or 18th): IONA/University College Dublin (UCD)+second university, - contact Joe Kiniry UCD, Sean Baker/Niall Donelly IONA) - Holger/Bea do talks about PyPy - methodology and tehnical aspects - - FIXED: Solution Linux 2006 (31st Januray-2nd Feb): - Logilab will present PyPy in the "free software models" track in Paris. - - OPEN: PyCon, 24th-26th Feburary: michael/holger/christian/armin want to submit one or two proposals - and go there, also doing a py lib and/or pypy-sprint. Bea wants to submit methodology talk. - Note that sprints are scheduled after the conf. - DEADLINE: 30th October (in two weeks!) - - OPEN: 3 of March 2006 Sk?vde Sweden, CALIBRE Workshop on Distributed Development, - Open Source & Industry- Opportunities, Suspicions, & Strategies (Bea) - - OPEN: ACCU 19th-22nd April 2005 (michael, jacob) - Submission date:? - - OPEN: XP 2006, 17-22th June 2006 Oulu Finland - Submission date: 1 march 2006 (methodology talk/workshop?/Bea) - - OPEN: 3-5th July 2006 Europython Cern Switzerland - Submission date: ? - - OPEN: OOPSLA 2006 (Samuele, Armin) - Submission date: probably 20th March 2006 - - OPEN: Calibre conferences - - OPEN: Agile Alliance conferences? - Submission date: ? - - -EU-related Workpackage planning phase 2 -------------------------------------------------- - -- WP09 and WP10 done and coordinated by logilab/dfki - people. they should update the rest of us regarding - planning and also communicate regarding - possible related sprint topics. - -- WP02 dev infrastructure is merlinux responsibility, - should also suggest sprint topics (considering e.g. - a py lib sprint at PyCon ...) - -- other WPs in phase 2 are probably more generally in - common responsibility (like WP04/WP05) with the lead - partner taking special responsibility (towards the EU): - - - WP03 (HHU) synchronisation CPython - - WP06 (HHU) core optimisations - - WP07 (tismerysoft) translator optimisations - - WP08 (Strakt) dynamic optimisations - - WP14 (Changemaker) dissemination/project representation - - open: - - - WP05: left over work for Impara (when they get accepted)? - - -EU-related report planning -------------------------------------------------- - -People (primary) and co-reviewers (secondary) and completion dates: -(lead partner coordinating, technical board evaluating overall consistency) - -DO1.1 Create QA plan for the project -Primary/Secondary: Bea/Holger -Completion date: 21th Oct 2005 - -D04.1 Partial Python Impl: -Primary/Secondary: Jacob / Christian -Completion date: 28th Oct 2005 - -D04.2 Complete Python Impl: -Primary/Secondary: Jacob / Christian -Completion date: 4th Nov 2005 - -D04.3 Parser report: -Primary/Secondary: ludovic,adrien / Arre -Completion date: 11th Nov 2005 - -D04.4 Release PyPy-research-tool: -Primary/Secondary: Samuele / Ludovic -Completion date: 11th Nov 2005 - -D05.1 Publish on translating a very-high-level description: -Primary/Secondary: Armin / Michael -Completion date: 4th Nov 2005 - -D05.2 A compiled, self-contained version of PyPy: -Primary/Secondary: dfki/Anders L. / Jacob -Completion date: 28th Oct 2005 - -D05.3 Publish on implementation with translation aspects: -Primary/Secondary: Carl / Armin, Christian -Completion date: TBA - -D05.4 Publish on encapsulating low level language aspects: -Primary/Secondary: Armin / holger -Completion date: TBA - -D14.1 Report about Milestone/Phase 1: -Primary/Secondary: Bea/Stephan -Completion date:21th October 2005 - -Review planning: - -Roadmap: - -*31th October 2005: all partners check completeness of timesheets Dec 2004-Oct 2005 -(Stephan wp1, Jacob wp3,4,5, Bea wp14, all partners) - -*5th December 2005: all partners submit timesheets for November 2005 -(Stephan wp1, Jacob wp3,4,5, Bea wp14, all partners) - -*9th December 2005: Periodic management/activity reports updated with all data but costs -(Jacob//Bea) - -*15th December 2005: submit reports to EC/reviewers -(Stephan) - -*16th December 2005: all partners submit FORM C:s to DFKI (or communicate a new - completion date for this!) -(Stephan, all partners) - -*10th January 2006: review in Brussels -(Stephan) - -*15th of January 2006: submit FORM C:s to EC/PO and possible updated periodic management/ -activity reports -(Stephan//Jacob,Bea + +Rough preparation draft for saturday-afternoon 20051015 meeting Paris +------------------------------------------------------------- + +work group/pairing status +------------------------------ + +- ootypes / rtyper refactoring: + Boris reports: continued to refactor rypting into + non-ll specific and ll-specific parts. still a lot + of work to be done (currently you can specialize + an empty class with the oo-type system). + bert: squeak backend uses the oo-type system and + creates squeak class definitions. (oo-types are + built manually there at the moment). + +- socket module: + all the interface is wrapped/implemented at interpreter-level + and is reusing the underlying (cpython) socket module. There is + not translation/external function calls yet (which will introduce + platform issues). + +- numeric module: + started the basic Array type, you can construct such types that + contain floats or integers, and you can have efficient slices + (reusing the same underlying array). The base Array class + is not connected to storage, subclasses are (specific to floats/ints). + +- l3interpreter: + have a refined very-low-level flow graph model, and we can + pass in integers and do addition. also the l3intepreter + is translateable and passes tests. + +- compiler issues + ran the core compliancy tests (failing ones are mostly + due to missing weakref support). problem is that we + are having a mix of all slightly incorrect compiler + (or at least don't know if they/which are correct) + variations. It seems to make more sense to contribute the + whole astcompiler rather than trying to come up with patches + to the CPython version. + +- translation issues: + compliance tests start to run on pypy-c (test_builtin.py) + but there are likely more bugs/issues lurking. + christian is working on locality of references by + analysing flowgraphs. + +pypy technical task planning +---------------------------------- + +Identify tasks to be done in between sprints, start with +see paris-2005-possible-tasks.txt: + +- full compiler/parser integration + +- pypy-sync meetings should constantly track/amend/modify those + technical tasks and in general focus on technical issues + NOTE though: pypy-sync cannot focus too much on EU requirements + because it's a more open/community forum. + +- idea is to collect all larger tasks and bring plannings + to the pypy-sync meetings. Carl is going to do the next + pypy-sync meeting. Send plans/larger task plannings to + the moderators and don't wait until the moderator generates + the idea himself. + + +sprints & conferences +------------------------- + + next sprint: 5-11th December in Sweden (Change Maker?/G?tabergsgatan?) + Gborg. + + *(10 th January eu review workshop) + + *23-29th January: CS Dep. of the Palma de Mallorca University/CS Dep. of the Barcelona University + Bea check dates, Bruxelles/Louvain-la-neuve, Holger check dates), + + *27 Feb - 1st March: PyCon (24-26 Feb, 2006 Dallas, Texas, + postsprint, Michael/Holger, Armin, Christian, Bea), DEADLINE 30th + October + + *April Japan: (1) April 23 to April 29, (2) April 30 to May 5, contact: Yutaka Niibe, + National Institute of AIST, Japan (FSIJ) Akihabara, Tokyo (Bea), venue for 32 people. + (However, check with the EU). + + * (IBM workshop possibly end June, holger) + *6-9th (?) July: Europython Cern (3-5th July maybe in Leysin (Armin) Swizerland, + and the post-sprint at CERN, Michael/Holger) + + *21-27th August: University of Limerick/Ireland (Bea), maybe good possibility + to present pypy results to researchers. + + * 2-8th October: ? + * November: closure sprint + + Other possibilities: Romania, Switzerland (Leysin,Bern), Bristol, Uganda (Nkozi), bruxelles + +- Conference/y?talks planning: + + FIXED:27th October2005 PMI Chapter Sweden, methodology/PyPy talk in Link?ping (Bea) + + HALF-FIXED: 8th December 2005 Calibre/agile development workshop in + Bruxelles, Bea, Holger, Alastair attending (or maybe + just two persons). Bea coordinates (Alastair?). + + HALF-FIXED: CCC 27th-30th December Berlin (pypy technical talk accepted, + non-technical talk pending, may be unlikely, holger is keeping + contact) + + HALF-FIXED: 17th January 2006 (16th and or 18th): IONA/University College Dublin (UCD)+second university, + contact Joe Kiniry UCD, Sean Baker/Niall Donelly IONA) + Holger/Bea do talks about PyPy - methodology and tehnical aspects + + FIXED: Solution Linux 2006 (31st Januray-2nd Feb): + Logilab will present PyPy in the "free software models" track in Paris. + + OPEN: PyCon, 24th-26th Feburary: michael/holger/christian/armin want to submit one or two proposals + and go there, also doing a py lib and/or pypy-sprint. Bea wants to submit methodology talk. + Note that sprints are scheduled after the conf. + DEADLINE: 30th October (in two weeks!) + + OPEN: 3 of March 2006 Sk?vde Sweden, CALIBRE Workshop on Distributed Development, + Open Source & Industry- Opportunities, Suspicions, & Strategies (Bea) + + OPEN: ACCU 19th-22nd April 2005 (michael, jacob) + Submission date:? + + OPEN: XP 2006, 17-22th June 2006 Oulu Finland + Submission date: 1 march 2006 (methodology talk/workshop?/Bea) + + OPEN: 3-5th July 2006 Europython Cern Switzerland + Submission date: ? + + OPEN: OOPSLA 2006 (Samuele, Armin) + Submission date: probably 20th March 2006 + + OPEN: Calibre conferences + + OPEN: Agile Alliance conferences? + Submission date: ? + + +EU-related Workpackage planning phase 2 +------------------------------------------------- + +- WP09 and WP10 done and coordinated by logilab/dfki + people. they should update the rest of us regarding + planning and also communicate regarding + possible related sprint topics. + +- WP02 dev infrastructure is merlinux responsibility, + should also suggest sprint topics (considering e.g. + a py lib sprint at PyCon ...) + +- other WPs in phase 2 are probably more generally in + common responsibility (like WP04/WP05) with the lead + partner taking special responsibility (towards the EU): + + - WP03 (HHU) synchronisation CPython + - WP06 (HHU) core optimisations + - WP07 (tismerysoft) translator optimisations + - WP08 (Strakt) dynamic optimisations + - WP14 (Changemaker) dissemination/project representation + + open: + + - WP05: left over work for Impara (when they get accepted)? + + +EU-related report planning +------------------------------------------------- + +People (primary) and co-reviewers (secondary) and completion dates: +(lead partner coordinating, technical board evaluating overall consistency) + +DO1.1 Create QA plan for the project +Primary/Secondary: Bea/Holger +Completion date: 21th Oct 2005 + +D04.1 Partial Python Impl: +Primary/Secondary: Jacob / Christian +Completion date: 28th Oct 2005 + +D04.2 Complete Python Impl: +Primary/Secondary: Jacob / Christian +Completion date: 4th Nov 2005 + +D04.3 Parser report: +Primary/Secondary: ludovic,adrien / Arre +Completion date: 11th Nov 2005 + +D04.4 Release PyPy-research-tool: +Primary/Secondary: Samuele / Ludovic +Completion date: 11th Nov 2005 + +D05.1 Publish on translating a very-high-level description: +Primary/Secondary: Armin / Michael +Completion date: 4th Nov 2005 + +D05.2 A compiled, self-contained version of PyPy: +Primary/Secondary: dfki/Anders L. / Jacob +Completion date: 28th Oct 2005 + +D05.3 Publish on implementation with translation aspects: +Primary/Secondary: Carl / Armin, Christian +Completion date: TBA + +D05.4 Publish on encapsulating low level language aspects: +Primary/Secondary: Armin / holger +Completion date: TBA + +D14.1 Report about Milestone/Phase 1: +Primary/Secondary: Bea/Stephan +Completion date:21th October 2005 + +Review planning: + +Roadmap: + +*31th October 2005: all partners check completeness of timesheets Dec 2004-Oct 2005 +(Stephan wp1, Jacob wp3,4,5, Bea wp14, all partners) + +*5th December 2005: all partners submit timesheets for November 2005 +(Stephan wp1, Jacob wp3,4,5, Bea wp14, all partners) + +*9th December 2005: Periodic management/activity reports updated with all data but costs +(Jacob//Bea) + +*15th December 2005: submit reports to EC/reviewers +(Stephan) + +*16th December 2005: all partners submit FORM C:s to DFKI (or communicate a new + completion date for this!) +(Stephan, all partners) + +*10th January 2006: review in Brussels +(Stephan) + +*15th of January 2006: submit FORM C:s to EC/PO and possible updated periodic management/ +activity reports +(Stephan//Jacob,Bea From afa at codespeak.net Thu Oct 20 19:38:39 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Thu, 20 Oct 2005 19:38:39 +0200 (CEST) Subject: [pypy-svn] r18805 - pypy/dist/pypy/translator/c/test Message-ID: <20051020173839.1A1C427B6D@code1.codespeak.net> Author: afa Date: Thu Oct 20 19:38:37 2005 New Revision: 18805 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Simplify a socket test, and explain why it should not try all combinations: the C external functions do not have to handle type conversion. 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 Oct 20 19:38:37 2005 @@ -527,25 +527,6 @@ def test_socket(): import _socket import pypy.module._socket.rpython.exttable # for declare()/declaretype() - def fn(): - return _socket.ntohs(123) - f = compile(fn, []) - assert f() == _socket.ntohs(123) - def fn(): - return _socket.htons(123) - f = compile(fn, []) - assert f() == _socket.htons(123) - def fn(): - return _socket.ntohl(123) - f = compile(fn, []) - assert f() == _socket.ntohl(123) - def fn(): - return _socket.htonl(123) - f = compile(fn, []) - assert f() == _socket.htonl(123) - -def INPROGRESStest_NtoH(): - import _socket # This just checks that htons etc. are their own inverse, # when looking at the lower 16 or 32 bits. def fn1(n): @@ -560,14 +541,7 @@ compile(fn4, [int]): 16, compile(fn3, [int]): 16} for func, size in sizes.items(): mask = (1L< Author: arigo Date: Thu Oct 20 20:02:35 2005 New Revision: 18806 Added: pypy/dist/pypy/doc/draft-low-level-encapsulation.txt (contents, props changed) Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: (mwh, arigo) * started on the D05.4 documentation page: low-level translation aspects and contrasting them with CPython * progress on the proofs of draft-dynamic-language-translation.txt Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Thu Oct 20 20:02:35 2005 @@ -851,13 +851,13 @@ ~~~~~~~~~~~~~~~~~~~~~~ -.. _merge_into: +.. _merge: In the sequel, a lot of rules will be based on the following -``merge_into`` operator. Given an annotation *a* and a variable *x*, -``merge_into(a,x)`` modifies the state as follows:: +``merge`` operator. Given an annotation *a* and a variable *x*, +``merge a => x`` modifies the state as follows:: - merge_into(a,x): + merge a => x: if a=List(v) and b(x)=List(w): b' = b E' = E union (v ~ w) @@ -875,7 +875,7 @@ y = phi(x) ---------------------------------------- - merge_into(b(x),y) + merge b(x) => y The purpose of the equivalence relation *E* is to force two identified variables to keep the same binding. The rationale for this is explained @@ -884,8 +884,8 @@ (x~y) in E ---------------------------------------- - merge_into(b(x),y) - merge_into(b(y),x) + merge b(x) => y + merge b(y) => x Note that a priori, all rules should be tried repeatedly until none of them generalizes the state any more, at which point we have reached a @@ -966,7 +966,7 @@ setitem(x,y,z), b(x)=List(v) -------------------------------------------- - merge_into(b(z),v) + merge b(z) => v Reading an item out a list requires care to ensure that the rule is rescheduled if the binding of the hidden variable is generalized. We do @@ -981,7 +981,7 @@ E' = E union (z'~v) b' = b with (z->b(z')) -If you consider the definition of `merge_into`_ again, you will notice +If you consider the definition of `merge`_ again, you will notice that merging two different lists (for example, two lists that come from different creation points via different code paths) identifies the two hidden variables. This effectively identifies the two lists, as if they @@ -999,7 +999,7 @@ E' = E union (v~w) b' = b with (z->List(v)) -As with `merge_into`_, it identifies the two lists. +As with `merge`_, it identifies the two lists. Prebuilt constants @@ -1119,7 +1119,8 @@ setattr(x,attr,z), b(x)=Inst(C) --------------------------------------------------------------------- E' = E union (v_C.attr ~ v_D.attr) for all D subclass of C - merge_into(b(z), v_C.attr) + check b(z) for the absence of potential bound method objects + merge b(z) => v_C.attr Note the similarity with the ``getitem`` and ``setitem`` of lists, in particular the usage of the auxiliary variable *z'*. @@ -1151,6 +1152,17 @@ * among the methods bound to ``C`` or superclasses of ``C``, only the one from the most derived class. +Finally, note that we still allow real bound methods to be handled quite +generically, in the way that is quite unique to Python: if ``meth`` is +the name of a method of *x*, then ``y = x.meth`` is allowed, and the +object *y* can be passed around and stored in data structures. However, +we do not allow such objects to be stored directly back into other +instances (it is the purpose of the check in the rule for ``setattr``). +This would create a confusion between class-level and instance-level +attributes in a subsequent ``getattr``, because our annotator does not +distinguish these two levels -- there is only one set of ``v_C.attr`` +variables for both. + Calls ~~~~~ @@ -1166,23 +1178,23 @@ for each c in set: if c is a function: E' = E union (z ~ returnvar_c) - merge_into(b(y1), arg_c_1) + merge b(y1) => arg_c_1 ... - merge_into(b(yn), arg_c_n) + merge b(yn) => arg_c_n if c is a class: let f = c.__init__ - merge_into(Inst(c), z) - merge_into(Inst(c), arg_f_1) - merge_into(b(y1), arg_f_2) + merge Inst(c) => z + merge Inst(c) => arg_f_1 + merge b(y1) => arg_f_2 ... - merge_into(b(yn), arg_f_(n+1)) + merge b(yn) => arg_f_(n+1) if c is a method: let class.f = c E' = E union (z ~ returnvar_f) - merge_into(Inst(class), arg_f_1) - merge_into(b(y1), arg_f_2) + merge Inst(class) => arg_f_1 + merge b(y1) => arg_f_2 ... - merge_into(b(yn), arg_f_(n+1)) + merge b(yn) => arg_f_(n+1) Calling a class returns an instance and flows the annotations into the contructor ``__init__`` of the class. Calling a method inserts the @@ -1202,23 +1214,91 @@ *********** We first have to check that each rule can only turn a state *(b,E)* into -a state *(b',E')* that is either identical or more general. To do so, -we first verify that they all have the following properties: +a state *(b',E')* that is either identical or more general. Clearly, +*E'* can only be generalized -- applying a rule can only add new +identifications, not remove existing ones. What is left to check is +that the annotation ``b(v)`` of each variable, when modified, can only +become more general. We prove it in the following order: + +1. the annotations ``b(v_C.attr)`` of variables corresponding to + attributes on classes; + +2. the annotations of the input variables of blocks; + +3. the annotations of the auxiliary variable of operations; + +4. the annotations of the input and result variables of operations. + +Proof: + +1. Variables corresponding to attributes of classes + + The annotation of such variables can only be modified by the + ``setattr`` rule and by being identified with other variables, + i.e. by the ``(x~y) in E`` rule. In both cases the modification + is done with a ``merge``. The latter trivially guarantees the + property of generalization, as it is based on the union operator + ``\/`` of the lattice. + +2. Input variables of blocks + + The annotation of these variables are only modified by the + ``phi`` rule, which is based on ``merge``. + +3. Auxiliary variables of operations + + The auxiliary variable *z'* of an operation is only ever modified + by being identified with other variables. + +4. Input and result variables of operations + + First note that the result variable *z* of an operation is only + ever modified by the rule or rules specific to that operation. + This is true because *E* never identifies such a result variable + with any other variable. This allows us to check the property of + generalization on a case-by-case basis. + + For a given block, we prove this point by recurrence on the + number of operations present in the block. The recurrence is + based on the fact that each input variable of an operation must + be either the result variable of a previous operation of the same + block or an input variable of the block. By the point 2 above, + if it is an input variable of the block then it can only get + generalized, as desired. So the recurrence step only needs to + check that if all the input variables of an operation can only be + generalized, then the same property holds for its result + variable. + + Most cases are easy to check. Cases like ``b' = b with + (z->b(z'))`` are based on point 3 above. The only non-trivial + case is in the rule for ``getattr``:: + + b' = b with (z->lookup_filter(b(z'), C)) + + The class ``C`` comes from the annotation ``Inst(C)`` of an input + variable. This is where the recurrence hypothesis is needed. It + is enough to prove that given annotations ``a1 <= a2`` and + ``Inst(C1) <= Inst(C2)``, we have:: + + lookup_filter(a1, Inst(C1)) <= lookup_filter(a2, Inst(C2)) + + The only interesting case is if ``a1 = Pbc(set1)`` and ``a2 = + Pbc(set2)``. In this case *set1* is a subset of *set2*. ... + + XXX first prove that the sets are "reasonable": if C.f in set, + then D.f in set for all parent classes D + + +STOP + +using the previous point, this can be checked on the rule (or rules) of +each operation independently. Indeed, there are only two ways in which +``b(z)`` is modified: by ``merge .. => z``, which trivially +guarantees the property by being based on the union operator ``\/`` of +the lattice, or explicitely in a way that can easily be checked to +respect the property. -* if *z* is the result variable of an operation, the binding ``b(z)`` is - only ever modified by the rule (or rules) about this operation: this - is true because *E* never identifies such a result variable with any - other variable. - -* the annotation ``b(z)`` of such a result variable can only become more - general: using the previous point, this can be checked on the rule (or - rules) of each operation independently. Indeed, there are only two - ways in which ``b(z)`` is modified: by ``merge_into(..., z)``, which - trivially guarantees the property by being based on the union operator - ``\/`` of the lattice, or explicitely in a way that can easily be - checked to respect the property. -... Each basic step (execution of one rule) can lead to the generalization Added: pypy/dist/pypy/doc/draft-low-level-encapsulation.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/draft-low-level-encapsulation.txt Thu Oct 20 20:02:35 2005 @@ -0,0 +1,120 @@ +============================================================ + Encapsulating low-level implementation aspects +============================================================ + +.. contents:: +.. sectnum:: + + +Abstract +=============================================== + +It has always been a major goal of PyPy to not make implementation +decisions. This means that even after the interpreter and core objects +are implemented we want to be able to make decisions about aspects such +as garbage collection strategy, target platform or even execution model. + +In the following document, we expose these aspects in more detail and +contrast the potential of our approach with CPython. + + +Background +=============================================== + +One of the better known significant modifications to CPython are +Christian Tismer's "stackless" patches [#]_, which allow for far more +flexible control flow than the typical function call/return supported by +CPython. Originally implemented as a series of invasive patches, +Christian found that maintaining these patches as CPython itself was +further developed was time consuming to the point of no longer being +able to work on the new functionality that was the point of the +exercise. + +One solution would have been for the patches to become part of core +CPython but this was not done partly because the code that fully enabled +stackless required widespread modifications that made the code harder to +understand (as the "stackless" model contains control flow that is not +naturally expressable in C, the implementation became much less +"natural" in some sense). + +With PyPy, however, it is possible to obtain this flexible control flow +with transparent implementation code as the necessary modifications can +be implemented as a localized translation aspect, and indeed this was +done at the Paris sprint in a couple of days (as compared to XXX weeks +for the original stackless patches). + +Of course, this is not the only aspect that can be so decided a +posteriori, during translation. + +.. [#] http://www.stackless.com + + +Translation aspects +=============================================== + +Our standard interpreter[#]_ is implemented at a very high level of +abstraction. This has a number of happy consequences, among which is +enabling the encapsulation of language aspects described in this +document. The implementation code simply makes no reference to memory +management, for example, which gives the translator complete freedom to +decide about this aspect. This constrasts with CPython where the +decision to use reference counting is reflected tens or even hundreds of +times in each C source file in the codebase. + +.. [#] "standard interpreter" in this context means the code which + implements the interpreter and the standard object space. + +As described in `...`_, producing a Python implementation from the +source of our standard interpreter involves various stages: the +initialization code is run, the resulting code is annotated, specialized +and finally translated. By the nature of the task, the encapsulation of +*low-level aspects* mainly affects the specializer and the translation +process. At the coarsest level, the selection of target platform +involves writing a new backend -- still a significant task, but much +much easier than writing a complete implementation of Python! + +Other aspects affect different levels, as their needs require. The +stackless modifications for instance are mostly implemented in the C +backend but also change the low-level graphs in small ways. The total +changes only required about 300 lines of source, vindicating our +abstract approach. + +Another implementation detail that causes tension between functionality +and both code clarity and memory consumption in CPython is the issue of +multiple independent interpreters in the same process. In CPython there +is a partial implementation of this idea in the "interpreter state" API, +but the interpreters produced by this are not truly independent -- for +instance the dictionary that contains interned strings is implemented as +file-level static object, and is thus shared between the interpreters. +A full implementation of this idea would entirely eschew the use of file +level statics and place all interpreter-global data in some large +structure, which would hamper readability and maintainability. In +addition, in many situations it is necessary to determine which +interpreter a given object is "from" -- and this is not possible in +CPython largely because of the memory overhead that adding a 'interp' +pointer to all Python objects would create. + +Because all of our implementation code manipulates an object space +instance, the situation of multiple interpreters is handled entirely +automatically. If there is only one space instance, it is regarded as a +pre-constructed constant and the space object pointer (though not all of +its contents) disappears from the produced source. If there are two or +more such instances, a 'space' attribute will be automatically added to +all application objects, the best of both worlds. + +The aspect of CPython's implementation that has probably caused more +discussion than any other mentioned here is that of the threading model. +Python has supported threads since version 1.5 with what is commonly +referred to as a "Global Interpreter Lock" or GIL; the execution of +bytecodes is serialized such that only one thread can be executing +Python code at one time. This has the benefit of being relatively +unintrisive and not too complex, but has the disadvantage that +multi-threaded computation-bound Python code does not gain performance +on multi-processing machines. + +PyPy will offer the opportunity to experiment with different models, +although currently only offers a version with no thread support and +another with a GIL-like model. + + +.. _`...`: http://www.example.com From cfbolz at codespeak.net Thu Oct 20 21:29:25 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Oct 2005 21:29:25 +0200 (CEST) Subject: [pypy-svn] r18807 - pypy/dist/pypy/tool Message-ID: <20051020192925.8E42327B6A@code1.codespeak.net> Author: cfbolz Date: Thu Oct 20 21:29:20 2005 New Revision: 18807 Modified: pypy/dist/pypy/tool/statistic_over_time.py Log: reduce the number of countlots that are done Modified: pypy/dist/pypy/tool/statistic_over_time.py ============================================================================== --- pypy/dist/pypy/tool/statistic_over_time.py (original) +++ pypy/dist/pypy/tool/statistic_over_time.py Thu Oct 20 21:29:20 2005 @@ -34,12 +34,7 @@ olddate = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) date = olddate while date == olddate: - counter, nf, nl, ntf, ntl = get_loccount([pypy.localpath]) num_revs += 1 - num_files = max(num_files, nf) - num_testfiles = max(num_testfiles, ntf) - num_lines = max(num_lines, nl) - num_testlines = max(num_testlines, ntl) olddate = date try: tempdir.update(rev=curr_rev - 1) @@ -47,8 +42,10 @@ tempdir.localpath.remove(1) tempdir.localpath.mkdir() tempdir.checkout(URL, rev=curr_rev - 1) - curr_rev = tempdir.info(usecache=0).rev - date = datetime.date(*time.gmtime(pypy.info(0).mtime)[:3]) + info = tempdir.info(usecache=0) + curr_rev = info.rev + date = datetime.date(*time.gmtime(info.mtime)[:3]) + counter, num_files, num_lines, num_testfiles, num_testlines = get_loccount([pypy.localpath]) print date, num_revs, num_files, num_testfiles, num_lines, num_testlines statistic.append([date, num_revs, num_files, num_testfiles, num_lines, num_testlines]) finally: From mwh at codespeak.net Thu Oct 20 22:33:40 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 20 Oct 2005 22:33:40 +0200 (CEST) Subject: [pypy-svn] r18808 - pypy/dist/pypy/doc Message-ID: <20051020203340.2C4FD27B69@code1.codespeak.net> Author: mwh Date: Thu Oct 20 22:33:39 2005 New Revision: 18808 Modified: pypy/dist/pypy/doc/draft-low-level-encapsulation.txt Log: more words for what will become D05.4. i think that's enough translation aspects to be going on with. probably each aspect deserves it's own section and a few more words each. please read, fix typos etc. Modified: pypy/dist/pypy/doc/draft-low-level-encapsulation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-low-level-encapsulation.txt (original) +++ pypy/dist/pypy/doc/draft-low-level-encapsulation.txt Thu Oct 20 22:33:39 2005 @@ -2,6 +2,17 @@ Encapsulating low-level implementation aspects ============================================================ +.. so this mentions the following aspects: + threading + gc policy + target platform + stacklessness + supporting multiple interpreter states + the thunk object space. + + it does so in a very boring "here's one aspect, here's another" + sort of way. this needs to change. it's probably also too short. + .. contents:: .. sectnum:: @@ -46,13 +57,10 @@ Of course, this is not the only aspect that can be so decided a posteriori, during translation. -.. [#] http://www.stackless.com - - Translation aspects =============================================== -Our standard interpreter[#]_ is implemented at a very high level of +Our standard interpreter [#]_ is implemented at a very high level of abstraction. This has a number of happy consequences, among which is enabling the encapsulation of language aspects described in this document. The implementation code simply makes no reference to memory @@ -61,9 +69,6 @@ decision to use reference counting is reflected tens or even hundreds of times in each C source file in the codebase. -.. [#] "standard interpreter" in this context means the code which - implements the interpreter and the standard object space. - As described in `...`_, producing a Python implementation from the source of our standard interpreter involves various stages: the initialization code is run, the resulting code is annotated, specialized @@ -73,6 +78,8 @@ involves writing a new backend -- still a significant task, but much much easier than writing a complete implementation of Python! +.. _`...`: http://www.example.com + Other aspects affect different levels, as their needs require. The stackless modifications for instance are mostly implemented in the C backend but also change the low-level graphs in small ways. The total @@ -114,7 +121,42 @@ PyPy will offer the opportunity to experiment with different models, although currently only offers a version with no thread support and -another with a GIL-like model. +another with a GIL-like model. XXX Could speculatively waffle here +easily enough. +A final low-level aspect is that of memory management. As mentioned +above, CPython's decision to use a garbage collector based on +reference counting is reflected throughout the source. In the +implementation code of PyPy, it is not, and in fact the standard +interpreter can currently be compiled to use a reference counted +scheme or Boehm's `garbage collector for C`_. + +.. _`garbage collector for C`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ + +Another advantage of the aspect oriented approach shows itself most +clearly with this memory management aspect: that of correctness. +Although reference counting is a fairly simple scheme, writing code +for CPython requires that the programmer make a large number of +not-quite-trivial decisions about the refcounting code and experience +suggests that mistakes will always creep in, leading to crashes or +leaks. While tools exist to help find these mistakes, it is surely +better to not write the reference count manipulations at all and this +is what PyPy's approach allows. Writing the code that emits the +correct reference count manipulations is surely harder than writing +any one piece of explicit refcounting code, but once it's done and +tested, you it just works without further effort. + +Possibly the most radical aspect to tinker with is the evaluation +strategy. The thunk object space wraps the standard object space to +allow the production of "lazily computed objects", objects whose +values are only calculated when needed, and to allow the global and +total replacement of one object with another. The thunk object space +is mostly meant as an example of what our approach can acheive -- the +combination of side-effects and lazy evaluation is not easy to +understand. + +.. [#] "standard interpreter" in this context means the code which + implements the interpreter and the standard object space. + +.. [#] http://www.stackless.com -.. _`...`: http://www.example.com From cfbolz at codespeak.net Thu Oct 20 23:48:01 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 20 Oct 2005 23:48:01 +0200 (CEST) Subject: [pypy-svn] r18810 - pypy/dist/pypy/tool Message-ID: <20051020214801.0FF8227B69@code1.codespeak.net> Author: cfbolz Date: Thu Oct 20 23:48:00 2005 New Revision: 18810 Modified: pypy/dist/pypy/tool/statistic_over_time.py Log: argh! in some revisions the directory http://codespeak.net/svn/pypy/dist does not exist Modified: pypy/dist/pypy/tool/statistic_over_time.py ============================================================================== --- pypy/dist/pypy/tool/statistic_over_time.py (original) +++ pypy/dist/pypy/tool/statistic_over_time.py Thu Oct 20 23:48:00 2005 @@ -38,10 +38,20 @@ olddate = date try: tempdir.update(rev=curr_rev - 1) + except KeyboardInterrupt: + raise except: tempdir.localpath.remove(1) tempdir.localpath.mkdir() - tempdir.checkout(URL, rev=curr_rev - 1) + while 1: + try: + tempdir.checkout(URL, rev=curr_rev - 1) + except KeyboardInterrupt: + raise + except: + curr_rev -= 1 + else: + break info = tempdir.info(usecache=0) curr_rev = info.rev date = datetime.date(*time.gmtime(info.mtime)[:3]) From arigo at codespeak.net Fri Oct 21 13:56:10 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Oct 2005 13:56:10 +0200 (CEST) Subject: [pypy-svn] r18819 - pypy/dist/pypy/interpreter Message-ID: <20051021115610.1006127B76@code1.codespeak.net> Author: arigo Date: Fri Oct 21 13:56:09 2005 New Revision: 18819 Modified: pypy/dist/pypy/interpreter/nestedscope.py pypy/dist/pypy/interpreter/pycode.py Log: We need a way to cope with changes of bytecode in CPython -- here MAKE_CLOSURE. Semi-hackishly stick the magic of CPython on the PyCode object if it is built from a CPython-compiled code object, and do the right thing depending on this magic number. We obviously need a better approach for flexible handling of bytecodes... Modified: pypy/dist/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/dist/pypy/interpreter/nestedscope.py (original) +++ pypy/dist/pypy/interpreter/nestedscope.py Fri Oct 21 13:56:09 2005 @@ -168,14 +168,18 @@ w_codeobj = f.valuestack.pop() codeobj = f.space.interpclass_w(w_codeobj) assert isinstance(codeobj, pycode.PyCode) - nfreevars = len(codeobj.co_freevars) - freevars = [] - for i in range(nfreevars): - cell = f.space.interpclass_w(f.valuestack.pop()) - if not isinstance(cell, Cell): - raise pyframe.BytecodeCorruption - freevars.append(cell) - freevars.reverse() + if codeobj.magic >= 0xa0df281: # CPython 2.5 AST branch merge + w_freevarstuple = f.valuestack.pop() + freevars = f.space.unpacktuple(w_freevarstuple) + else: + nfreevars = len(codeobj.co_freevars) + freevars = [] + for i in range(nfreevars): + cell = f.space.interpclass_w(f.valuestack.pop()) + if not isinstance(cell, Cell): + raise pyframe.BytecodeCorruption + freevars.append(cell) + freevars.reverse() defaultarguments = [f.valuestack.pop() for i in range(numdefaults)] defaultarguments.reverse() fn = function.Function(f.space, codeobj, f.w_globals, Modified: pypy/dist/pypy/interpreter/pycode.py ============================================================================== --- pypy/dist/pypy/interpreter/pycode.py (original) +++ pypy/dist/pypy/interpreter/pycode.py Fri Oct 21 13:56:09 2005 @@ -80,6 +80,8 @@ class PyCode(eval.Code): "CPython-style code objects." + + magic = 62061 | 0x0a0d0000 # value for Python 2.4.1 def __init__(self, space, co_name=''): self.space = space @@ -105,7 +107,7 @@ def _code_new( self, argcount, nlocals, stacksize, flags, code, consts, names, varnames, filename, name, firstlineno, lnotab, freevars, cellvars, - hidden_applevel=False): + hidden_applevel=False, from_cpython=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 @@ -143,12 +145,20 @@ newconsts_w = [] for const in consts: if isinstance(const, types.CodeType): # from stable compiler - const = PyCode(space)._from_code(const, hidden_applevel=hidden_applevel) + const = PyCode(space)._from_code(const, hidden_applevel=hidden_applevel, + from_cpython=from_cpython) newconsts_w.append(space.wrap(const)) self.co_consts_w = newconsts_w + # stick the underlying CPython magic value, if the code object + # comes from there + if from_cpython: + import imp, struct + magic, = struct.unpack(" Author: pedronis Date: Fri Oct 21 14:27:17 2005 New Revision: 18820 Added: pypy/dist/pypy/translator/goal/targetthunkstandalone.py - copied, changed from r18804, pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: a target to translated pypy with the thunk objspace. From mwh at codespeak.net Fri Oct 21 14:33:05 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 21 Oct 2005 14:33:05 +0200 (CEST) Subject: [pypy-svn] r18821 - pypy/dist/pypy/translator/goal Message-ID: <20051021123305.F318C27B7B@code1.codespeak.net> Author: mwh Date: Fri Oct 21 14:33:05 2005 New Revision: 18821 Modified: pypy/dist/pypy/translator/goal/translate_pypy.py Log: exec the targetblah.py file with a given __name__ -- otherwise classes defined in the file end up with a __module__ of __builtin__ and hilarity ensues. 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 Oct 21 14:33:05 2005 @@ -149,7 +149,7 @@ log.info("Translating target as defined by %s" % targetspec) if not targetspec.endswith('.py'): targetspec += '.py' - targetspec_dic = {} + targetspec_dic = {'__name__':'__rpythonmain__'} sys.path.insert(0, os.path.dirname(targetspec)) execfile(targetspec, targetspec_dic) return targetspec_dic From arigo at codespeak.net Fri Oct 21 14:48:05 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Oct 2005 14:48:05 +0200 (CEST) Subject: [pypy-svn] r18822 - in pypy/dist/pypy/interpreter: . test Message-ID: <20051021124805.02FF727B7B@code1.codespeak.net> Author: arigo Date: Fri Oct 21 14:48:05 2005 New Revision: 18822 Modified: pypy/dist/pypy/interpreter/miscutils.py pypy/dist/pypy/interpreter/test/test_syntax.py Log: Just adding comments and helpful error messages. Modified: pypy/dist/pypy/interpreter/miscutils.py ============================================================================== --- pypy/dist/pypy/interpreter/miscutils.py (original) +++ pypy/dist/pypy/interpreter/miscutils.py Fri Oct 21 14:48:05 2005 @@ -79,7 +79,7 @@ def pop(self): ptr = self.ptr - 1 - ret = self.items[ptr] + ret = self.items[ptr] # you get OverflowError if the stack is empty self.items[ptr] = None self.ptr = ptr return ret Modified: pypy/dist/pypy/interpreter/test/test_syntax.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_syntax.py (original) +++ pypy/dist/pypy/interpreter/test/test_syntax.py Fri Oct 21 14:48:05 2005 @@ -254,12 +254,16 @@ for s in VALID: try: compile(s, '?', 'exec') - except: + except Exception, e: + print '-'*20, 'FAILED TO COMPILE:', '-'*20 print s - raise + print '%s: %s' % (e.__class__, e) + print '-'*60 for s in INVALID: try: raises(SyntaxError, compile, s, '?', 'exec') - except: + except Exception ,e: + print '-'*20, 'UNEXPECTEDLY COMPILED:', '-'*20 print s - raise + print '%s: %s' % (e.__class__, e) + print '-'*60 From arigo at codespeak.net Fri Oct 21 15:06:09 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Oct 2005 15:06:09 +0200 (CEST) Subject: [pypy-svn] r18823 - pypy/dist/pypy/doc Message-ID: <20051021130609.CF73327B7B@code1.codespeak.net> Author: arigo Date: Fri Oct 21 15:06:08 2005 New Revision: 18823 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Changed the nesting of sections and subsections (mwh comment). Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 21 15:06:08 2005 @@ -35,7 +35,7 @@ No Declarations --------------------------- +~~~~~~~~~~~~~~~ The notion of "declaration", central in compiled languages, is entirely missing in Python. There is no aspect of a program that must be declared; @@ -71,7 +71,7 @@ The analysis of live programs ------------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ How can we perform some static analysis on a program written in a dynamic language while keeping to the spirit of `No Declarations`_, i.e. without @@ -133,7 +133,7 @@ ====================================================== Object Spaces ---------------------------------- +~~~~~~~~~~~~~ The semantics of Python can be roughly divided in two groups: the syntax of the language, which focuses on control flow aspects, and the object semantics, @@ -162,7 +162,7 @@ Abstract interpretation ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~ In the sequel of this paper, we will consider another application of the object space separation. The analysis we perform in PyPy @@ -209,15 +209,26 @@ The PyPy analysis toolchain -=========================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We developed above a theoretical point of view that differs +significantly from what we have implemented, for many reasons. The +devil is in the details. + +The rest of this document is organized as follows: -The previous sections have developed a theoretical point of view that -differs significantly from what we have implemented, for many reasons. -The devil is in the details. +* the `Flow Object Space`_ chapter describes how we turn Python bytecode + objects into control flow graphs by performing its abstract + interpretation; + +* the `Annotator`_ chapter describes our type inference model and process; + +* the `Code Generation`_ chapter gives an overview about how we turn + annotated flow graphs into low-level code. Flow Object Space ---------------------------------- +=========================================== In our bytecode-interpreter design evaluation responsibilities are split between the Object Space, frames and the so-called execution @@ -506,7 +517,7 @@ Annotator ---------------------------------- +================================= The annotator is the type inference part of our toolchain. The annotator infers *types* in the following sense: given a program @@ -1358,8 +1369,10 @@ XXX termination even with non-static aspects -Code generation: rewriting to low-level operations --------------------------------------------------- +Code Generation +=============================== + +XXX rewriting to low-level operations XXX introduction, repr From pedronis at codespeak.net Fri Oct 21 15:50:15 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 21 Oct 2005 15:50:15 +0200 (CEST) Subject: [pypy-svn] r18824 - pypy/dist/pypy/doc Message-ID: <20051021135015.0F85027B6E@code1.codespeak.net> Author: pedronis Date: Fri Oct 21 15:50:14 2005 New Revision: 18824 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: some draft intro paragraph about specialisation and polymorphism support Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 21 15:50:14 2005 @@ -1360,7 +1360,31 @@ Non-static aspects ~~~~~~~~~~~~~~~~~~ -XXX specialization (tons of fun) +Specialization +*************** + +The type system used by the annotator does not include polymorphism +support beyond object-oriented polymorphism with subclasses and +overriding and parametric polymorphism for builtin containers (lists, +...). In this respect we opted for simplicity, considering this in +most cases sufficient for the kind of system programming RPython is +aimed at and matching our main targets. It mostly eschews the +complexity of needing strategies to infer type parameters and to +control instantiation explosion or type erase and coalesce after the +fact, strategies that would also need to be target specific. + +We opted instead for either using the expressivity allowed for +bootstrap code which is unrestricted Python or having the annotator +support special explicit flags attached to functions or classes, +to achieve necessary forms of ad-hoc or parametric polymorphism when +the limited support for polymorphism in the annotator is insufficient +or in other cases to control what is effectively translated versus the +original code with annotation-time forms of specialization or even +substitution for code units (functions or classes). + +XXX details of what is supported + + XXX executing more user program code (idem) From mwh at codespeak.net Fri Oct 21 16:49:11 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 21 Oct 2005 16:49:11 +0200 (CEST) Subject: [pypy-svn] r18825 - pypy/dist/pypy/doc Message-ID: <20051021144911.EA50827B74@code1.codespeak.net> Author: mwh Date: Fri Oct 21 16:49:11 2005 New Revision: 18825 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: reword what samuele just wrote Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 21 16:49:11 2005 @@ -1365,22 +1365,24 @@ The type system used by the annotator does not include polymorphism support beyond object-oriented polymorphism with subclasses and -overriding and parametric polymorphism for builtin containers (lists, -...). In this respect we opted for simplicity, considering this in +overriding and parametric polymorphism for builtin containers (lists, +...). In this respect we opted for simplicity, considering this in most cases sufficient for the kind of system programming RPython is -aimed at and matching our main targets. It mostly eschews the -complexity of needing strategies to infer type parameters and to -control instantiation explosion or type erase and coalesce after the -fact, strategies that would also need to be target specific. - -We opted instead for either using the expressivity allowed for -bootstrap code which is unrestricted Python or having the annotator -support special explicit flags attached to functions or classes, -to achieve necessary forms of ad-hoc or parametric polymorphism when -the limited support for polymorphism in the annotator is insufficient -or in other cases to control what is effectively translated versus the -original code with annotation-time forms of specialization or even -substitution for code units (functions or classes). +aimed at and matching our main targets. + +Not all of our target code fits into this model. The fact that we +allow unrestricted dynamism at bootstrap helps a great deal, but in +addition we also support the explicit flagging of certain functions or +classes as requiring special treatment. One such special treatment is +support for parametric polymorphism, which if supported for all +callables would lead to an explosion of function implementations and +likely the need for some kind of target specific type erasure and +coalescing. + +Another special treatment is more outright special casing: providing +code to explicitly provide the annotation information for a give +function as opposed to abstractly interpreting the function's +bytecode. XXX details of what is supported From pedronis at codespeak.net Fri Oct 21 16:54:31 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 21 Oct 2005 16:54:31 +0200 (CEST) Subject: [pypy-svn] r18826 - pypy/dist/pypy/doc Message-ID: <20051021145431.386B127B74@code1.codespeak.net> Author: pedronis Date: Fri Oct 21 16:54:30 2005 New Revision: 18826 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: some fixes/rewordings Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 21 16:54:30 2005 @@ -1370,17 +1370,17 @@ most cases sufficient for the kind of system programming RPython is aimed at and matching our main targets. -Not all of our target code fits into this model. The fact that we -allow unrestricted dynamism at bootstrap helps a great deal, but in -addition we also support the explicit flagging of certain functions or -classes as requiring special treatment. One such special treatment is -support for parametric polymorphism, which if supported for all -callables would lead to an explosion of function implementations and -likely the need for some kind of target specific type erasure and -coalescing. +Not all of our target code or expressivity needs fit into this model. +The fact that we allow unrestricted dynamism at bootstrap helps a +great deal, but in addition we also support the explicit flagging of +certain functions or classes as requiring special treatment. One such +special treatment is support for parametric polymorphism, which if +supported for all callables would lead to an explosion of function +implementations and likely the need for some kind of target specific +type erasure and coalescing. Another special treatment is more outright special casing: providing -code to explicitly provide the annotation information for a give +code to explicitly compute the annotation information for a given function as opposed to abstractly interpreting the function's bytecode. From arigo at codespeak.net Fri Oct 21 17:03:14 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Oct 2005 17:03:14 +0200 (CEST) Subject: [pypy-svn] r18827 - pypy/dist/pypy/doc Message-ID: <20051021150314.7430A27B74@code1.codespeak.net> Author: arigo Date: Fri Oct 21 17:03:08 2005 New Revision: 18827 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Applying comments from mwh. (More to come.) Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 21 17:03:08 2005 @@ -27,11 +27,12 @@ these languages as mere libraries on top of some simpler (unspecified) language. -* Implementation-wise, language design is no longer driven by a desire to - enable high performance; any feature straightforward enough to achieve - with an interpreter is candidate. As a result, compilation and most - kinds of static inference are made impossible due to this dynamism - (unless they are simply tedious due to the size of the language). +* Implementation-wise, language design is no longer driven by a desire + to enable high performance; any feature straightforward enough to + achieve with an interpreter is a candidate for being accepted. As a + result, compilation and most kinds of static inference are made + impossible due to this dynamism (or at best tedious, due to the + complexity of the language). No Declarations @@ -55,7 +56,7 @@ could for example build a class in completely different ways based on the results of NP-complete computations or external factors. This is not just a theoretical possibility but a regularly used feature: for example, the -pure Python module ``os.py`` provides some OS-independent interface to +standard Python module ``os.py`` provides some OS-independent interface to OS-specific system calls, by importing internal OS-specific modules and completing it with substitute functions, as needed by the OS on which ``os.py`` turns out to be executed. Many large Python projects use custom @@ -103,31 +104,38 @@ in time. This is natural in image-oriented environments like Smalltalk, where the program resides in memory and not in files in the first place. -Our approach goes further and analyses *live* programs in memory: -the program is allowed to contain fully dynamic sections, as long as these -sections are entered a *bounded* number of times. -For example, the source code of the PyPy -interpreter, which is itself written in this bounded-dynamism style, makes -extensive use of the fact that it is possible to build new classes at any -point in time -- not just during an initialization phase -- as long as the -number of new classes is bounded. E.g. `interpreter/gateway.py`_ builds a -custom class -for each function that some variable can point to. There is a finite -number of functions in total, so this can obviously only create -a finite number of extra classes. But the precise set of functions that -need a corresponding class is difficult to manually compute in advance; -instead, the code that builds and cache a new class is invoked by the -analysis tool itself each time it discovers that a new function object can -reach the corresponding point. - -This approach is derived from dynamic analysis techniques that can support -unrestricted dynamic languages by falling back to a regular interpreter for -unsupported features (e.g. Psyco, described in -http://psyco.sourceforge.net/psyco-pepm-a.ps.gz). -The above argumentation should have shown why we think that being similarily -able to fall back to regular interpretation for parts that cannot be +Our approach goes further and analyses *live* programs in memory: the +program is allowed to contain fully dynamic sections, as long as these +sections are entered a *bounded* number of times. For example, the +source code of the PyPy interpreter, which is itself written in this +bounded-dynamism style, makes extensive use of the fact that it is +possible to build new classes at any point in time -- not just during an +initialization phase -- as long as the number of new classes is bounded. +For example, `interpreter/gateway.py`_ builds a custom wrapper class +corresponding to each function that a particular variable can reference. +There is a finite number of functions in total, so this can only create +a finite number of extra wrapper classes. But the precise set of +functions that need such a wrapper class is difficult to manually +compute in advance. It would also be redundant to do so: indeed, it is +part of the type inference tool's job to discover all functions that can +reach each point in the program. In this case, whenever it discovers +that a new function could reach the particular variable mentioned above, +the analysis tool itself will invoke the class-building code in +`interpreter/gateway.py`_ as part of the inference process. This +triggers the building of the necessary wrapper class, implicitely +extending the set of classes that need to be analysed. (This is +essentially done by a hint that marks the code building the wrapper +class for a given function as requiring memoization.) + +This approach is derived from dynamic analysis techniques that can +support unrestricted dynamic languages by falling back to a regular +interpreter for unsupported features (e.g. [Psyco]_). The above +argumentation should have shown why we think that being similarily able +to fall back to regular interpretation for parts that cannot be understood is a central feature of the analysis of dynamic languages. +.. [Psyco] http://psyco.sourceforge.net/ or the `ACM SIGPLAN 2004 paper`_. + Concrete and abstract interpretation ====================================================== @@ -151,11 +159,11 @@ considers objects as black boxes; any operation on objects requested by the bytecode is handled over to the object library, called *object space*. The point of this architecture is, precisely, that neither of these two -components is trivial; separating them explicitely, with a well-defined +components is trivial; separating them explicitly, with a well-defined interface inbetween, allows each part to be reused independently. This is a major flexibility feature of PyPy: we can for example insert proxy object -spaces in front of the real one, like the `Thunk Object Space`_ adding lazy -evaluation of objects. +spaces in front of the real one, as in the `Thunk Object Space`_ which adds +lazy evaluation of objects. Note that the term "object space" has already been reused for other dynamic language implementations, e.g. XXX for Perl 6. @@ -182,14 +190,16 @@ flow object space for static enough functions, and a standard, concrete object space for functions or initializations requiring the full dynamism. -If the placeholders are endowed with a bit more information, e.g. if they -carry a type information that is propagated to resulting placeholders by -individual operations, then our abstract interpretation simultaneously -performs type inference. This is, in essence, executing the program while -abstracting out some concrete values and replacing them with the set of -all values that could actually be there. If the sets are broad enough, -then after some time we will have seen all potential value sets along each -possible code paths, and our program analysis is complete. +If, for example, the placeholders are endowed with a bit more +information, e.g. if they carry a type information that is propagated to +resulting placeholders by individual operations, then our abstract +interpretation simultaneously performs type inference. This is, in +essence, executing the program while abstracting out some concrete +values and replacing them with the set of all values that could actually +be there. If the sets are broad enough, then after some time we will +have seen all potential value sets along each possible code paths, and +our program analysis is complete. (Note that this is not exactly how +`the PyPy analysis toolchain`_ does type inference: see below.) An object space is thus an *interpretation domain*; the Flow Object Space is an *abstract interpretation domain*. We are thus interpreting the @@ -202,10 +212,10 @@ we switch to the concrete level. The restrictions placed on the program to statically analyse are that to be crafted in such a way that this process eventually terminates; from this point of view, more abstract is better (it -covers whole sets of objects in a single pass). Thus the compromize that +covers whole sets of objects in a single pass). Thus the compromises that the author of the program to analyse faces are less strong but more subtle -than not using a specific set of dynamic features at all, but using them -sparsingly enough. +than a rule forbidding most dynamic features. The rule is, roughly +speaking, to use dynamic features sparsingly enough. The PyPy analysis toolchain @@ -213,19 +223,23 @@ We developed above a theoretical point of view that differs significantly from what we have implemented, for many reasons. The -devil is in the details. - -The rest of this document is organized as follows: +devil is in the details. Our toolchain is organized in three main +passes, each described in its own chapter in the sequel: * the `Flow Object Space`_ chapter describes how we turn Python bytecode objects into control flow graphs by performing its abstract interpretation; -* the `Annotator`_ chapter describes our type inference model and process; +* the `Annotator`_ chapter describes our type inference model and process, + by doing abstract interpretation of the control flow graphs; * the `Code Generation`_ chapter gives an overview about how we turn annotated flow graphs into low-level code. +The third pass is further divided into turning the control flow graphs +into low-level ones, generating (e.g.) C source code for a C compiler, +and invoking the C compiler to actually produce the executable. + Flow Object Space =========================================== @@ -236,20 +250,18 @@ interpretation engine, while the object space implements all operations on values which are treated as black boxes by the engine. -The Object Space plays the role of a factory for execution contexts, -whose base implementation is supplied by the engine, and exposes hooks -triggered when frames are entered, left and before each bytecode, -allowing to gather a trace of the execution. - -Frames have run/resume methods which embed the interpretation loop, -These methods take an execution context invoking the appropriate hooks -at the corresponding situations. +The Object Space plays the role of a factory for execution contexts. +The base implementation of execution contexts is supplied by the engine, +and exposes hooks triggered when frames are entered and left and before +each bytecode, allowing a trace of the execution to be gathered. Frames +have run/resume methods which embed the interpretation loop and invoke +the hooks at the appropriate times. The Flow Object Space in our current design is responsible of constructing a flow graph for a single function using abstract interpretation. The domain on which the Flow Space operates comprises variables and constant objects. They are stored as such in the frame -objects without problems because by design the interpreter engine treat +objects without problems because by design the interpreter engine treats them as black boxes. @@ -270,18 +282,18 @@ The Flow Space constructs the flow graph, operation after operation, as a side effect of seeing these operations performed by the interpretation -of the bytecode. During construction, blocks in the graph all have an -associated frame state. The Flow Space start from an empty block with an -a frame state corresponding to a frame freshly initialized, with a new -variables for each input argument of the analysed function. It proceeds -by recording the operations in this block, as follows: when an operation -is delegated to the Flow Space by the frame interpretation loop, either -a constant result is produced -- in the case of constant arguments to an -operation with no side-effects -- or a fresh new variable is produced. -In the latter case, the operation (together with its input variables and -constant arguments, and its output variable) is recorded in the current -block and the new variable is returned as result to the frame -interpretation loop. +of the bytecode. During construction, the operations are grouped in +basic blocks that all have an associated frame state. The Flow Space +starts from an empty block with a frame state corresponding to a freshly +initialized frame, with a new variable for each input argument of the +analysed function. It proceeds by recording the operations into this +fresh block, as follows: when an operation is delegated to the Flow +Space by the frame interpretation loop, either a constant result is +produced -- in the case of constant arguments to an operation with no +side-effects -- or a fresh new variable is produced. In the latter +case, the operation (together with its input variables and constant +arguments, and its output variable) is recorded in the current block and +the new variable is returned as result to the frame interpretation loop. When a new bytecode is about to be executed, as signalled by the bytecode hook, the Flow Space considers the frame state corresponding to @@ -296,15 +308,18 @@ In more details, "similar enough" is defined as having the same position-dependant part, the so-called "non-mergeable frame state", which mostly means that only frame states corresponding to the same -bytecode position can ever be merged. This process thus produces blocks -that are generally in one-to-one correspondance with the bytecode -positions seen so far. The exception to this rule is in the rare cases +bytecode position can ever be merged. This process thus produces basic +blocks that are generally in one-to-one correspondance with the bytecode +positions seen so far [#]_. The exception to this rule is in the rare cases where frames from the same bytecode position have a different non-mergeable state, which typically occurs during the "finally" part of a "try: finally:" construct, where the details of the exception handler stack differs according to whether the "finally" part was entered normally or as a result of an exception. +.. [#] this creates many small basic blocks; for convenience, a + post-processing phase merges them into larger blocks when possible. + If two states have the same non-mergeable part, they can be merged using a "union" operation: only two equal constants unify to a constant of the same value; all other combinations (variable-variable or @@ -316,7 +331,7 @@ state is strictly more general than the existing one, then the existing block is cleared, and we proceed with the generalized state, reusing the block. (Reusing the block avoids the proliferation of over-specific -blocks. Ror example, without this, all loops would typically have their +blocks. For example, without this, all loops would typically have their first pass unrolled with the first value of the counter as a constant; instead, the second pass through the loop that the Flow Space does with the counter generalized as a variable will reuse the same entry point @@ -335,9 +350,11 @@ so that we can pretend that ``is_true`` returns twice into the engine, once for each possible answer, so that the Flow Space can record both outcomes. Without proper continuations in Python, we have implemented a -more explicit scheme that we describe below. (The approach is related -to the one used in Psyco_, where continuations would be entierely -inpractical, as described in the `ACM SIGPLAN 2004 paper`_.) +more explicit scheme (describe below) where the execution context and +the object space collaborate to emulate this effect. (The approach is +related to the one used in [Psyco]_, where regular continuations would +be entirely impractical due to the need of huge amounts of them -- as +described in the `ACM SIGPLAN 2004 paper`_.) At any point in time, multiple pending blocks can be scheduled for abstract interpretation by the Flow Space, which proceeds by picking one @@ -376,15 +393,18 @@ list of outcomes until we reach the desired state. This is implemented by having a special blocks (called ``EggBlocks`` -internally, whereas normal blocks are ``SpamBlocks``) return a chain of -recorders: one so-called "replaying" recorder for each of the parent -blocks in the tree, followed by a normal recorder for the block itself. -When the engine replays the execution from the root of the tree, the -intermediate recorders check (for consistency) that the same operations -as the ones already recorded are issued again, ending in a call to -``is_true``; at this point, the replaying recorder gives the answer -corresponding to the branch to follow, and switch to the next recorder -in the chain. +internally, whereas normal blocks are ``SpamBlocks`` [#]_) return a +chain of recorders: one so-called "replaying" recorder for each of the +parent blocks in the tree, followed by a normal recorder for the block +itself. When the engine replays the execution from the root of the +tree, the intermediate recorders check (for consistency) that the same +operations as the ones already recorded are issued again, ending in a +call to ``is_true``; at this point, the replaying recorder gives the +answer corresponding to the branch to follow, and switch to the next +recorder in the chain. + +.. [#] "eggs, eggs, eggs, eggs and spam" -- references to Monthy Python + are common in Python :-) This mechanism ensures that all flow paths are considered, including different flow paths inside the engine and not only flow paths that are @@ -403,7 +423,8 @@ Note a limitation of this mechanism: the engine cannot use an unbounded loop to implement a single bytecode. All *loops* must still be explicitly present in the bytecodes. The reason is that the Flow Space -can only insert backlinks between bytecodes. +can only insert backlinks from the end of a bytecode to the beginning of +another one. Dynamic merging @@ -438,7 +459,7 @@ Note that this feature means that the Flow Space is not guaranteed to terminate. The analysed function can contain arbitrary computations on -constant values (with loops) that will be entierely constant-folded by +constant values (with loops) that will be entirely constant-folded by the Flow Space. A function with an obvious infinite loop will send the Flow Space following the loop ad infinitum. This means that it is difficult to give precise conditions for when the Flow Space terminates @@ -447,8 +468,12 @@ non-trivial constant computations at run-time; and the complexity of the Flow Space can more or less be bound by the run-time complexity of the constant parts of the function itself, if we ignore pathological cases -where a part of a function contains infinite loops but cannot be entered -at run-time for some reasons unknown to the Flow Space. +-- e.g. a function containing some infinite loops that cannot be reached +at run-time for reasons unknown to the Flow Space. + +However, barring extreme examples we can disregard pathological cases +because of testing -- we make sure that the code that we send to the +Flow Space is first well-tested. This philosophy will be seen again. Geninterp @@ -526,9 +551,9 @@ are the possible run-time objects that this variable will contain. Note that in the literature such an annotation is usually called a type, but we prefer to avoid this terminology to avoid confusion with the Python -notion of the concrete type of an object. Annotations are sets of -possible values that is not always exactly the set of all objects of a -specific Python type. +notion of the concrete type of an object. An annotation is a set of +possible values, and this set is not always exactly the set of all +objects of a specific Python type. We will first expose a simplified, static model of how the annotator works, and then hint at some differences between the model and the @@ -601,7 +626,7 @@ The flow graphs are in Static Single Information (SSI) form, an extension of Static Single Assignment (SSA_): each variable is only used in exactly one basic block. All variables that are not dead at the end -of a basic block are explicitely carried over to the next block and +of a basic block are explicitly carried over to the next block and renamed. Instead of the traditional phi functions of SSA we use a minor variant, parameter-passing style: each block declares a number of *input variables* playing the role of input arguments to the block; each link @@ -838,7 +863,7 @@ z=add(x,y), Char<=b(x)<=NullableStr, Char<=b(y)<=NullableStr ---------------------------------------------------------------- - b' = b with (z->Str) + b' = b with (z->Str) [see note below!] The rules are read as follows: for the operation ``z=add(x,y)``, we consider the bindings of the variables *x* and *y* in the current state @@ -852,7 +877,7 @@ applies as well. As none of these rules modify *E*, we also omitted the ``E'=E``. -Also note that we do not generally try to prove the correctness and +Also ``[note]`` that we do not generally try to prove the correctness and safety of the user program, preferring to rely on test coverage for that. This is apparent in the third rule above, which considers concatenation of two potentially "nullable" strings, i.e. strings that @@ -979,9 +1004,9 @@ -------------------------------------------- merge b(z) => v -Reading an item out a list requires care to ensure that the rule is +Reading an item out of a list requires care to ensure that the rule is rescheduled if the binding of the hidden variable is generalized. We do -so be identifying the hidden variable with the current operation's +so by identifying the hidden variable with the current operation's auxiliary variable. The identification ensures that the hidden variable's binding will eventually propagate to the auxiliary variable, which -- according to the metarule -- will reschedule the operation's @@ -999,8 +1024,8 @@ had the same origin. It makes the two list annotations aliases for each other, allowing any storage location to contain lists coming from any of the two sources indifferently. This process gradually builds a -partition of all lists in the program, where two lists are in the -partition if they are combined in any way. +partition of all lists in the program, where two lists are in the same +part if they are combined in any way. As an example of further list operations, here is the addition (which is the concatenation for lists):: @@ -1016,28 +1041,32 @@ Prebuilt constants ~~~~~~~~~~~~~~~~~~ -The ``Pbc`` annotations play a special role in our approach. They -regroup in a single family most of the constant user-defined objects -that pre-exist the annotation phase. This includes the functions and -classes defined in the user program, but also some other objects that -have been built while the user program was initializing itself. +The ``Pbc`` annotations play a special role in our approach. They group +in a single family all the constant user-defined objects that exist +before the annotation phase. This includes the functions and classes +defined in the user program, but also some other objects that have been +built while the user program was initializing itself. -The presence of the latter kind of objects -- which comes with a number -of new problems to solve -- is a distinguishing property of the idea of +The presence of the latter kind of object -- which come with a number of +new problems to solve -- is a distinguishing property of the idea of analysing a live program instead of static source code. All the user -objects that pre-exist the annotation phase are divided in two further -families: the "frozen prebuilt constants" ones and the "prebuilt -instances". By default, instances of some user-defined class that -happens to pre-exist annotation have no constantness requirement on -their own; after annotation and possibly compilation, these instances -will continue to behave as regular mutable instances of that class, -turned into mostly regular ``Inst(C)`` annotations when the annotator -encounters them. However, the user program can give a hint that forces -the annotator to consider the object as a "frozen prebuilt constant". -The object is then considered as a now-immutable container of -attributes. It looses its object-oriented aspects and its class becomes -irrelevant -- it was only useful to the user program to build the object -up to its current state. +objects that exist before the annotation phase are divided in two +further families: the "prebuilt instances" and the "frozen prebuilt +constants". + +1. Normally, all instances of user-defined classes have the same + behaviour, independently of whether they exist before annotation or are + built dynamically by the program after annotation and compilation. + Both correspond to the ``Inst(C)`` annotation. Instances that are + prebuilt will simply be compiled into the resulting executable as + prebuilt data structures. + +2. However, as an exception to 1., the user program can give a hint that + forces the annotator to consider such an object as a "frozen prebuilt + constant" instead. The object is then considered as an *immutable* + container of attributes. It loses its object-oriented aspects and its + class becomes irrelevant. It is not possible to further instantiate + its class at run-time. In summary, the prebuilt constants are: @@ -1046,7 +1075,7 @@ * all classes ``C`` of the user program; -* all frozen prebuilt constants; +* all frozen prebuilt constants. For convenience, we add the following objects to the above set: @@ -1055,15 +1084,16 @@ * the singleton None object (a special case of frozen prebuilt constant). -The annotation ``Pbc(*set*)`` stands for an object that belongs to the -specified *set* of prebuilt constant objects, which is a subset of all +The annotation ``Pbc(set)`` stands for an object that belongs to the +specified ``set`` of prebuilt constant objects, which is a subset of all the prebuilt constant objects. In practice, the set of all prebuilt constants is not fixed in advance, but grows while annotation discovers new functions and classes and -frozen user objects; only the objects that are still alive will be -included in the set, leaving out the ones that were only relevant during -the initialization phase of the program. +frozen prebuilt constants; in this way we can be sure that only the +objects that are still alive will be included in the set, leaving out +the ones that were only relevant during the initialization phase of the +program. Classes and instances @@ -1306,7 +1336,7 @@ each operation independently. Indeed, there are only two ways in which ``b(z)`` is modified: by ``merge .. => z``, which trivially guarantees the property by being based on the union operator ``\/`` of -the lattice, or explicitely in a way that can easily be checked to +the lattice, or explicitly in a way that can easily be checked to respect the property. @@ -1431,7 +1461,6 @@ .. _`join-semilattice`: http://en.wikipedia.org/wiki/Semilattice .. _`Flow Object Space`: objspace.html#the-flow-object-space .. _`Standard Object Space`: objspace.html#the-standard-object-space -.. _Psyco: http://psyco.sourceforge.net/ .. _`ACM SIGPLAN 2004 paper`: http://psyco.sourceforge.net/psyco-pepm-a.ps.gz .. _`Hindley-Milner`: http://en.wikipedia.org/wiki/Hindley-Milner_type_inference From arigo at codespeak.net Fri Oct 21 18:07:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Oct 2005 18:07:08 +0200 (CEST) Subject: [pypy-svn] r18828 - pypy/dist/pypy/doc Message-ID: <20051021160708.1696027B74@code1.codespeak.net> Author: arigo Date: Fri Oct 21 18:07:07 2005 New Revision: 18828 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: following comments from mwh, 2nd part. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 21 18:07:07 2005 @@ -510,7 +510,7 @@ flow graph into ``f_interp`` by generating for each operation a call to the corresponding method of ``space``. -This process looses the original syntactic structure of ``f_app``, +This process loses the original syntactic structure of ``f_app``, though; the flow graph is merely a collection of blocks that jump to each other. It is not always easy to reconstruct the structure from the graph (or even possible at all, in some cases where the flow graph does @@ -1101,26 +1101,25 @@ Remember that Python has no notion of classes declaring attributes and methods. Classes are merely hierarchical namespaces: an expression like -``obj.attr`` means that the ``attr`` attribute is looked up in the class -that ``obj`` is an instance of at run-time, and all parent classes (a -``getattr`` operation). Expressions like ``obj.meth()`` that look like +``obj.attr`` (a ``getattr`` operation) means that the ``attr`` attribute +is looked up in the class that ``obj`` is an instance of at run-time, +and all parent classes. Expressions like ``obj.meth()`` that look like method calls are actually grouped as ``(obj.meth)()``: they correspond to two operations, a ``getattr`` followed by a ``call``. The -intermediate object ``obj.meth`` is a bound method. +intermediate object returned by ``obj.meth`` is a bound method. -As the goal of annotator is to derive type information about the user -program that is static enough, it must reconstruct a static structure -for each class in the hierarchy. It does so by observing the usage -patterns of the classes and their instances, by propagating annotations -of the form ``Inst(cls)`` -- which stands for "an instance of the class -*cls* or any subclass". Instance fields are attached to a class -whenever we see that the field is being written to an instance of this -class. If the user program manipulates instances polymorphically, the -variables holding the instances will be annotated ``Inst(cls)`` with -some abstract base class *cls*; accessing attributes on such generalized -instances lifts the inferred attribute declarations up to *cls*. The -same technique works for inferring the location of both fields and -methods. +As the goal of annotator is to derive some static type information about +the user program, it must reconstruct a static structure for each class +in the hierarchy. It does so by observing the usage patterns of the +classes and their instances, by propagating annotations of the form +``Inst(cls)`` -- which stands for "an instance of the class *cls* or any +subclass". Instance fields are attached to a class whenever we see that +the field is being written to an instance of this class. If the user +program manipulates instances polymorphically, the variables holding the +instances will be annotated ``Inst(cls)`` with some abstract base class +*cls*; accessing attributes on such generalized instances lifts the +inferred attribute declarations up to *cls*. The same technique works +for inferring the location of both fields and methods. ~~~~~~~~~~~~~~~~~~~~~~ @@ -1132,14 +1131,14 @@ program point are instances of a user-defined common base class, i.e. not ``object``. -Remember from `definition of V`_ that we have a variable ``v_C.attr`` -for each class ``C`` and each possible attribute name ``attr``. The -annotation state *(b,E)* has the following meaning on these variables: - -* the binding map *b* gives an annotation to each of them, as with other - variables. The annotation ``b(v_C.attr)`` is the inferred type of the - values that can show up when the attribute ``attr`` is read out of an - instance of ``C``. +Remember from the `definition of V`_ that we have a variable +``v_C.attr`` for each class ``C`` and each possible attribute name +``attr``. The annotation state *(b,E)* gives the following meaning to +these variables: + +* the annotation ``b(v_C.attr)`` is the inferred type of the values that + can result from reading the attribute ``attr`` out of an instance of + ``C``; * to account for the inheritance between classes, the equivalence relation *E* identifies some of these variables as follows: if an @@ -1166,7 +1165,7 @@ Note the similarity with the ``getitem`` and ``setitem`` of lists, in particular the usage of the auxiliary variable *z'*. -The purpose of ``lookup_filter`` is to avoid loosing precision in method +The purpose of ``lookup_filter`` is to avoid losing precision in method calls. Indeed, if ``attr`` names a method of the class ``C`` then the binding ``b(v_C.attr)`` is initialized to ``Pbc(m)``, where *m* is the following set: @@ -1180,39 +1179,51 @@ superclass, the set *m* might end up containing potential bound methods of other unrelated subclasses of ``B``, even when performing a ``getattr`` on what we know is an instance of ``C``. The -``lookup_filter`` reverses this effect as follows:: +``lookup_filter`` reverses this effect. Its definition reflects where a +method lookup can actually find a method if it is performed on an +instance of an unspecified subclass of ``C``: either in one of these +subclasses, or in ``C`` or the closest parent class that defines the +method. If the method is also defined in further parents, these +definitions are hidden. More precisely:: - lookup_filter(Pbc(set), C) = Pbc(newset) + lookup_filter(Pbc(m), C) = Pbc(newset) lookup_filter(NonPbcAnnotation, C) = NonPbcAnnotation -where the *newset* only keeps the non-methods of *set* (if any) plus the -following methods: +where the *newset* is a subset of the set *m* with the following +objects: -* the ones bound to a strict subclass of ``C``, plus +* all the objects of *m* that are not potential bound method objects; + plus -* among the methods bound to ``C`` or superclasses of ``C``, only the - one from the most derived class. +* the potential bound method objects of *m* that are of the form + ``D.f``, where ``D`` is a strict subclass of ``C``; plus -Finally, note that we still allow real bound methods to be handled quite -generically, in the way that is quite unique to Python: if ``meth`` is +* among the potential bound method objects (if any) whose class is ``C`` + or a superclass of ``C``, we select the ones whose class is the most + derived class thus represented. In other words, if ``C`` inherits + from ``B`` which inherits from ``A``, then potential bound method + objects ``A.f`` would be included in the *newset* only if there is no + ``B.g`` or ``C.h`` in *m*. + +Finally, note that we still allow real bound methods to be handled and +passed around in the way that is quite unique to Python: if ``meth`` is the name of a method of *x*, then ``y = x.meth`` is allowed, and the object *y* can be passed around and stored in data structures. However, we do not allow such objects to be stored directly back into other instances (it is the purpose of the check in the rule for ``setattr``). This would create a confusion between class-level and instance-level -attributes in a subsequent ``getattr``, because our annotator does not -distinguish these two levels -- there is only one set of ``v_C.attr`` -variables for both. +attributes in a subsequent ``getattr``. It is a limitation of our +annotator to not distinguish these two levels -- there is only one set +of ``v_C.attr`` variables for both. Calls ~~~~~ -The ``Pbc`` annotations regroup (among others) all user-defined callable -objects: functions, methods and classes. A call in the user program -turns into a ``simplecall`` operation whose first argument is the object -to call. Here is the corresponding rule -- regrouping all cases because -the same ``Pbc(set)`` could mix several kinds of callables:: +A call in the user program turns into a ``simplecall`` operation whose +first argument is the object to call. Here is the corresponding rule -- +regrouping all cases because a single ``Pbc(set)`` annotation could mix +several kinds of callables:: z=simplecall(x,y1,...,yn), b(x)=Pbc(set) --------------------------------------------------------------------- @@ -1247,8 +1258,8 @@ Termination and soundness ~~~~~~~~~~~~~~~~~~~~~~~~~ -As the annotation process is a fix-point search, it is necessary for -completeness to prove more formally that it is well-behaved. The +As the annotation process is a fix-point search, we should prove for +completeness that it is, in some sense yet to define, well-behaved. The following proofs are all rather easy given the approach we have taken. Termination From arigo at codespeak.net Fri Oct 21 19:51:09 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 21 Oct 2005 19:51:09 +0200 (CEST) Subject: [pypy-svn] r18830 - in pypy/dist/pypy: module/posix module/posix/test translator/c/src translator/c/test Message-ID: <20051021175109.2B3BE27B7B@code1.codespeak.net> Author: arigo Date: Fri Oct 21 19:51:05 2005 New Revision: 18830 Modified: pypy/dist/pypy/module/posix/__init__.py pypy/dist/pypy/module/posix/interp_posix.py pypy/dist/pypy/module/posix/test/test_posix2.py pypy/dist/pypy/translator/c/src/ll_os.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Exported os.strerror(), which was already mostly there at RPython-level. Modified: pypy/dist/pypy/module/posix/__init__.py ============================================================================== --- pypy/dist/pypy/module/posix/__init__.py (original) +++ pypy/dist/pypy/module/posix/__init__.py Fri Oct 21 19:51:05 2005 @@ -37,6 +37,7 @@ 'rmdir' : 'interp_posix.rmdir', 'environ' : 'interp_posix.get(space).w_environ', 'listdir' : 'interp_posix.listdir', + 'strerror' : 'interp_posix.strerror', } 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 Fri Oct 21 19:51:05 2005 @@ -8,8 +8,11 @@ def wrap_oserror(space, e): assert isinstance(e, OSError) - errno = e.errno - msg = os.strerror(errno) + errno = e.errno + try: + msg = os.strerror(errno) + except ValueError: + msg = 'error %d' % errno w_error = space.call_function(space.w_OSError, space.wrap(errno), space.wrap(msg)) @@ -180,6 +183,16 @@ raise wrap_oserror(space, e) rmdir.unwrap_spec = [ObjSpace, str] +def strerror(space, errno): + 'strerror(code) -> string\n\nTranslate an error code to a message string.' + try: + text = os.strerror(errno) + except ValueError: + raise OperationError(space.w_ValueError, + space.wrap("strerror() argument out of range")) + return space.wrap(text) +strerror.unwrap_spec = [ObjSpace, int] + # this is a particular case, because we need to supply # the storage for the environment variables, at least @@ -245,6 +258,14 @@ return space.newlist(result) def listdir(space, dirname): + """listdir(path) -> list_of_strings + +Return a list containing the names of the entries in the directory. + +\tpath: path of directory to list + +The list is in arbitrary order. It does not include the special +entries '.' and '..' even if they are present in the directory.""" dir = ros.opendir(dirname) try: # sub-function call to make sure that 'try:finally:' will catch Modified: pypy/dist/pypy/module/posix/test/test_posix2.py ============================================================================== --- pypy/dist/pypy/module/posix/test/test_posix2.py (original) +++ pypy/dist/pypy/module/posix/test/test_posix2.py Fri Oct 21 19:51:05 2005 @@ -90,6 +90,10 @@ 'file1', 'file2'] + def test_strerror(self): + assert isinstance(self.posix.strerror(0), str) + assert isinstance(self.posix.strerror(1), str) + class AppTestEnvironment(object): def setup_class(cls): cls.space = space 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 Oct 21 19:51:05 2005 @@ -185,6 +185,11 @@ RPyString *LL_os_strerror(int errnum) { char *res; res = strerror(errnum); + if (res == NULL) { + RPyRaiseSimpleException(PyExc_ValueError, + "strerror() argument out of range"); + return NULL; + } return RPyString_FromString(res); } 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 Oct 21 19:51:05 2005 @@ -435,6 +435,14 @@ f1(dirname, True) assert not os.path.exists(dirname) +def test_strerror(): + def does_stuff(n): + return os.strerror(n) + f1 = compile(does_stuff, [int]) + for i in range(4): + res = f1(i) + assert res == os.strerror(i) + # ____________________________________________________________ def _real_getenv(var): From cfbolz at codespeak.net Fri Oct 21 20:28:52 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Fri, 21 Oct 2005 20:28:52 +0200 (CEST) Subject: [pypy-svn] r18832 - pypy/dist/pypy/tool Message-ID: <20051021182852.639A227B82@code1.codespeak.net> Author: cfbolz Date: Fri Oct 21 20:28:49 2005 New Revision: 18832 Modified: pypy/dist/pypy/tool/statistic_over_time.py Log: before the repository layout the interesting stuff is in trunk... Modified: pypy/dist/pypy/tool/statistic_over_time.py ============================================================================== --- pypy/dist/pypy/tool/statistic_over_time.py (original) +++ pypy/dist/pypy/tool/statistic_over_time.py Fri Oct 21 20:28:49 2005 @@ -43,6 +43,8 @@ except: tempdir.localpath.remove(1) tempdir.localpath.mkdir() + if curr_rev < 8359: + URL = "http://codespeak.net/svn/pypy/trunk" while 1: try: tempdir.checkout(URL, rev=curr_rev - 1) From tismer at codespeak.net Sat Oct 22 01:32:52 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 22 Oct 2005 01:32:52 +0200 (CEST) Subject: [pypy-svn] r18833 - in pypy/dist/pypy/translator: c locality Message-ID: <20051021233252.CF43027B83@code1.codespeak.net> Author: tismer Date: Sat Oct 22 01:32:49 2005 New Revision: 18833 Added: pypy/dist/pypy/translator/locality/support.py (contents, props changed) Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/locality/calltree.py pypy/dist/pypy/translator/locality/projection.py pypy/dist/pypy/translator/locality/simulation.py Log: current state of locality development. There were more problems than expected. Things solved here: * replaced debug prints with logging * kept the interface between simulation andflowgraphs to the minimum. Simulation/projection do not need to know anything about PyPy at all. * support for disjoint graphs being optimized independently * filtering of external functions, which appeared as infinite recursions * working in the projection space, only. Optimizing in multi dimensions is still supported by the code, but it turned out that this is overkill for the problem to be solved. * optimization of the lonelyness parameter works fine. But there is a problem with the starting conditions. I had cases where I started in a local minimum, and lonelyness was going up a bit, before showing monotonic decrease. Introduced a random initialization, which made this vanish. This is anyway no guarantee, but I think this is good enough. Open issues ----------- * tested with small targets only, yet * recursion is still weak. Need a way to isolate them, or they would dominate the simulation (although that might be no problem at all, have to play more) * convergence is achieved on the few tested graphs, only. The contraction algorithm seems to be very valid in general. I'm still researching about correct parameters on how much of the correction vectors to allow to be used. Several estimators failed so far and are not checked in. * functions held in variables are not captured, yet. This will be tried after a positive result. * the simulation approach seems to be quite good. I planned for a real benchmark, but meanwhile I like the simulation idea almost better. It might make sense to provide per-function calling probabilities by some heuristics; maybe we could also add properties to functions or even modules. * an initial test on stand-alone PyPy is still not done. Will hopefully be done, tomorrow. I'm a bit of fearful if this approach is useful at all. That's why I put so much preliminary work into it. If it fails, it should not be a mistake of my implementation. Note: I'm again over time budget with this, and tomorrow will be the last day spent on it. I hereby put a 5 % minimum speed gain on the simulated thing. If this is not met, the whole locality folder gets into the attic. I think I have spent four full days on this, now. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sat Oct 22 01:32:49 2005 @@ -10,6 +10,7 @@ from pypy.rpython.rmodel import getfunctionptr from pypy.rpython import lltype from pypy.tool.udir import udir +from pypy.translator.locality.calltree import CallTree class CBuilder(object): c_source_filename = None @@ -175,6 +176,9 @@ self.funcnodes = funcnodes self.othernodes = othernodes self.path = path + return # the below is under development + graph = CallTree(self.funcnodes, self.database) + graph.simulate() def uniquecname(self, name): assert name.endswith('.c') Modified: pypy/dist/pypy/translator/locality/calltree.py ============================================================================== --- pypy/dist/pypy/translator/locality/calltree.py (original) +++ pypy/dist/pypy/translator/locality/calltree.py Sat Oct 22 01:32:49 2005 @@ -28,10 +28,24 @@ """ from pypy.objspace.flow.model import Variable, Constant +from pypy.translator.locality.support import log +from pypy.translator.locality.simulation import SimNode, SimGraph +from pypy.translator.locality.projection import SpaceNode, SpaceGraph + + +class FlowSimNode(SimNode): + def _get_name(self, func): + return func.name + + def _find_callee_names(self): + calls = self.sim.clientdata[self.func] + return [func.name for func in calls] + class CallTree: - def __init__(self, funcnodes): + def __init__(self, funcnodes, database): self.nodes = funcnodes + self.database = database self.graphs2nodes = self._build_graph2nodes() self.calls = {} for node in self.nodes: @@ -46,6 +60,10 @@ def find_callees(self, node): graph = node.obj.graph res = [] + if node.obj._callable in self.database.externalfuncs: + s = "skipped external function %s" % node.obj._callable.__name__ + log.calltree.findCallees(s) + return res for block in graph.iterblocks(): for op in block.operations: if op.opname == 'direct_call': @@ -57,10 +75,20 @@ try: callednode = self.graphs2nodes[graph] except KeyError: - print "No node found for graph %s" % graph.name + s = "No node found for graph %s" % graph.name + log.calltree.findCallees(s) continue else: res.append(callednode) else: - print "Node %s calls Variable %s" % (node, fnarg) + s = "Node %s calls Variable %s" % (node.name, fnarg) + log.calltree.findCallees(s) return res + + def simulate(self): + log.calltree('building CallTree...') + sim = SimGraph(self.nodes, FlowSimNode, self.calls) + log.calltree('simulating...') + sim.sim_all(0.9, 50) + import pdb + pdb.set_trace() Modified: pypy/dist/pypy/translator/locality/projection.py ============================================================================== --- pypy/dist/pypy/translator/locality/projection.py (original) +++ pypy/dist/pypy/translator/locality/projection.py Sat Oct 22 01:32:49 2005 @@ -25,49 +25,279 @@ The weighted distance between two nodes """ -from pypy.translator.locality.simulation import DemoNode, DemoSim from math import sqrt +import random + + +def zipextend(v1, v2): + adjust = len(v2) - len(v1) + if adjust: + if adjust > 0: + v1 += [0.0] * adjust + else: + v2 = v2[:] + [0.0] * -adjust + return zip(v1, v2) + + +class Vector: + # a really dumb little helper class + + def __init__(self, seq=None): + self.coords = list(seq or []) + + def __inplace_add__(self, other): + self.coords = [p + q for p, q in zipextend(self.coords, other.coords)] + + def __inplace_sub__(self, other): + self.coords = [p - q for p, q in zipextend(self.coords, other.coords)] + + def __inplace_mul__(self, scalar): + if isinstance(scalar, Vector): + # dot product. zip is correct here, zero cancels. + other = scalar + self.coords = [p * q for p, q in zip(self.coords, other.coords)] + else: + # scalar product + self.coords = [p * scalar for p in self.coords] + + def __inplace_div__(self, scalar): + self.coords = [p / scalar for p in self.coords] + + def __add__(self, other): + vec = Vector(self.coords) + vec.__inplace_add__(other) + return vec + + def __sub__(self, other): + vec = Vector(self.coords) + vec.__inplace_sub__(other) + return vec + + def __mul__(self, scalar): + vec = Vector(self.coords) + vec.__inplace_mul__(scalar) + return vec + + def __div__(self, scalar): + vec = Vector(self.coords) + vec.__inplace_div__(scalar) + return vec + + def __neg__(self): + return Vector([-k for k in self.coords]) + + def norm2(self): + return sqrt(sum([k * k for k in self.coords])) + + def getdim(self): + return len(self.coords) + + # access to coordinates + def __getitem__(self, idx): + return self.coords[idx] + + def __setitem__(self, idx, value): + self.coords[idx] = value + + def __iter__(self): + return iter(self.coords) + + def __repr__(self): + return 'Vector(%r)' % self.coords class SpaceNode: def __init__(self, node): self.func = node.func self.name = node.name - def setup(self, relations, weights): + def setup(self, relations, weights, initpos): self.relations = relations self.weights = weights - self.position = weights[:] # just anything to start with + self.position = initpos def distance(self, other): # using the nice property of zip to give the minimum length - dist = 0.0 - for x1, x2 in zip(self.position, other.position): - d = x2 - x1 - dist += d * d - return sqrt(dist) + return (other.position - self.position).norm2() + + def scale(self, factor): + self.position *= factor + + def shift(self, delta): + self.position += delta + + def shiftx(self, deltax): + self.position[0] += deltax def lonelyness(self): - # get the sum of weighted distances - lonely = 0.0 + # get the square norm of weighted distances + lonely = [] for weight, relative in zip(self.weights, self.relations): - lonely += weight * self.distance(relative) - return lonely + lonely.append(weight * self.distance(relative)) + return Vector(lonely).norm2() + + def forcevector(self): + # weighted implementation of the "rubber2" algorithm, + # from "PolyTop", (C) Christian Tismer / Gerhard G. Thomas 1992 + vec = self.position * 0.0 + for w, rel in zip(self.weights, self.relations): + tmp = rel.position - self.position + lng = tmp.norm2() + tmp *= w * lng + vec += tmp + # this is a little faster than + # vec += (rel.position - self.position) * w * self.distance(rel) + return vec - def corrvector(self): - pass # XXX continue here class SpaceGraph: + random = random.Random(42).random + def __init__(self, simgraph): + self.nodes = [] + self.addgraph(simgraph) + self.lastdim = 0 # calculated by normalize + self.subgraphs = [] + + def addgraph(self, simgraph): mapping = {} for simnode in simgraph.nodes: mapping[simnode] = SpaceNode(simnode) - self.nodes = [mapping[simnode] for simnode in simgraph.nodes] + i = len(self.nodes) + self.nodes += [mapping[simnode] for simnode in simgraph.nodes] for simnode in simgraph.nodes: relations, weights = simnode.get_relations() relations = [mapping[rel] for rel in relations] node = mapping[simnode] - node.setup(relations, weights) + # extreme simplification: + # use just one dimension + # scamble as much as possible to avoid + # starting in a local minimum + #node.setup(relations, weights, Vector([i])) + node.setup(relations, weights, Vector([self.random()])) + i += 1 + self.subgraphs = [] + + def xminmax(self, nodes=None): + nodes = nodes or self.nodes + xaxis = [node.position[0] for node in nodes] + xmin = min(xaxis) + xmax = max(xaxis) + return float(xmin), float(xmax) + + def compute_subgraphs(self): + nodes = {} + for node in self.nodes: + nodes[node] = node + self.subgraphs = [] + while nodes: + for node in nodes: + break + todo = [node] + del nodes[node] + for node in todo: + for rel in node.relations: + if rel in nodes: + del nodes[rel] + todo.append(rel) + self.subgraphs.append(todo) + + def normalize(self): + # identify disjoint subgraphs. + # for every subgraph: + # move the graph center to zero + # scale the graph to make the x-axis as long as the number of nodes. + # shift all graphs to be in disjoint intervals on the x-axis. + if not self.subgraphs: + self.compute_subgraphs() + def distort(nodes): + # stretch collapsed x-axis + for i, node in enumerate(nodes): + node.position[0] = i + return nodes + def norm_subgraph(nodes, start): + # normalize a subgraph, return the dimensionality as side effect + xmin, xmax = self.xminmax(nodes) + xwidth = xmax - xmin + if not xwidth: # degenerated + return norm_subgraph(distort(nodes)) + factor = (len(nodes) - 1) / xwidth + mean = Vector() + for node in nodes: + mean += node.position + mean /= len(nodes) + shift = -mean + dim = shift.getdim() + for node in nodes: + node.shift(shift) + node.scale(factor) + shiftx = start - (xmin + shift[0]) * factor + for node in nodes: + node.shiftx(shiftx) + return dim + + start = 0.0 + dim = 0 + for nodes in self.subgraphs: + dim = max(dim, norm_subgraph(nodes, start)) + start += len(nodes) + self.lastdim = dim + + def do_correction(self, korr=0.13): + forcevecs = [node.forcevector() for node in self.nodes] + corrx = [vec[0] for vec in forcevecs] + maxcorr = abs(max(corrx)) + xmin, xmax = self.xminmax() + xwidth = xmax - xmin + scale = xwidth / maxcorr + scale = scale * korr + for node, forcevec in zip(self.nodes, forcevecs): + corrvec = forcevec * scale + node.shift(corrvec) + + def squeeze_dim(self): + scale = [] + ndim = self.lastdim + for i in range(ndim): + scale.append( 1.01 ** -i ) + scale = Vector(scale) + for node in self.nodes: + node.scale(scale) + + def lonelyness2(self): + # square norm of lonelynesses + lonely = [] + for node in self.nodes: + lonely.append(node.lonelyness()) + return Vector(lonely).norm2() + + def lonelyness(self): + # square norm of lonelynesses + lonely = 0.0 + for node in self.nodes: + lonely += node.lonelyness() + return lonely / len(self.nodes) + + def order(self): + sorter = [(node.position[0], node) for node in self.nodes] + sorter.sort() + return [node for x, node in sorter] + + def display(self): + for node in self.order(): + print node.name, node.lonelyness(), node.position if __name__ == '__main__': - from pypy.translator.locality.simulation import test + from pypy.translator.locality.simulation import SimGraph + def test(): + def a(): b() + def b(): c() + def c(): d() + def d(): e() + def e(): f() + def f(): a() + sim = DemoSim([a, b, c, d, e, f]) + sim.sim_all(0.9, 50) + return sim g = SpaceGraph(test()) + g.addgraph(test()) + g.addgraph(test()) Modified: pypy/dist/pypy/translator/locality/simulation.py ============================================================================== --- pypy/dist/pypy/translator/locality/simulation.py (original) +++ pypy/dist/pypy/translator/locality/simulation.py Sat Oct 22 01:32:49 2005 @@ -7,20 +7,20 @@ in the call-graph of a program, to gather information about frequencies of transitions between functions. -The following DemoNode/DemoSim classes show an example of the +The following SimNode/SimGraph classes show an example of the simulation performed. They can be subclassed to connect them to client structures like flowgraphs. -- DemoSim.run was used to get an obviously correct reference implementation. +- SimGraph.run was used to get an obviously correct reference implementation. -- DemoSim.sim_all simulates the calls of the run method. The results are +- SimGraph.sim_all simulates the calls of the run method. The results are exactly the same, although the computation time ir orders of magnitudes - smaller, and the DemoSim.simulate method is able to handle recursions + smaller, and the SimGraph.simulate method is able to handle recursions and function call probabilities which are fractions. """ -class DemoNode: +class SimNode: def __init__(self, sim, func): self.sim = sim self.func = func @@ -84,11 +84,13 @@ freqs, nodes = zip(*ret) return nodes, [-freq for freq in freqs] -class DemoSim: - def __init__(self, funcnodes, nodefactory=DemoNode): + +class SimGraph: + def __init__(self, funcnodes, nodefactory=SimNode, clientdata=None): self.nodes = [] self.transitions = {} self.pending = {} + self.clientdata = clientdata name2node = {} for func in funcnodes: @@ -127,15 +129,16 @@ self.transitions[key] = 0 for node in self.nodes: node.clear() + self.pending.clear() def display(self): d = {'w': max(self._names_width, 6) } - print '%%%(w)ds %%%(w)ds repetition' % d % ('caller', 'callee') + print '%%%(w)ds %%%(w)gs repetition' % d % ('caller', 'callee') for caller, callee, reps in self.get_state(): - print '%%%(w)ds %%%(w)ds %%6d' % d % (caller, callee, reps) - print '%%%(w)ds calls' % d % 'node' + print '%%%(w)ds %%%(w)gs %%6g' % d % (caller, callee, reps) + print '%%%(w)gs calls' % d % 'node' for node in self.nodes: - print '%%%(w)ds %%6d' % d % (node.name, node.calls) + print '%%%(w)gs %%6g' % d % (node.name, node.calls) def get_state(self): lst = [] @@ -166,11 +169,15 @@ pending[callee] = pending.get(callee, 0) + ntrans * call_prob self.pending = pending - def sim_all(self, call_prob=1, root=None): - # for testing, only. Would run infinitely with recursions. + def sim_all(self, call_prob=1, maxrun=None, root=None): + # simulate and stop after maxrun loops self.simulate(call_prob, root) + i = 0 while self.pending: self.simulate(call_prob) + i += 1 + if maxrun and i >= maxrun: + break def _compute_callers(self): nodes = {} @@ -192,12 +199,12 @@ def c(): pass def d(): c(); e() def e(): c() - sim = DemoSim([a, b, c, d, e]) + sim = SimGraph([a, b, c, d, e]) if debug: globals().update(locals()) sim.clear() - for prob in 1, 2, 3: + for prob in 1, 3, 2: sim.clear() sim.run_all(prob) state1 = sim.get_state() Added: pypy/dist/pypy/translator/locality/support.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/locality/support.py Sat Oct 22 01:32:49 2005 @@ -0,0 +1,6 @@ +# logging + +import py +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer("locality") +py.log.setconsumer("locality", ansi_log) From tismer at codespeak.net Sat Oct 22 01:49:05 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sat, 22 Oct 2005 01:49:05 +0200 (CEST) Subject: [pypy-svn] r18834 - pypy/dist/pypy/translator/locality Message-ID: <20051021234905.7118127B83@code1.codespeak.net> Author: tismer Date: Sat Oct 22 01:49:04 2005 New Revision: 18834 Modified: pypy/dist/pypy/translator/locality/calltree.py Log: forgot to save before committing Modified: pypy/dist/pypy/translator/locality/calltree.py ============================================================================== --- pypy/dist/pypy/translator/locality/calltree.py (original) +++ pypy/dist/pypy/translator/locality/calltree.py Sat Oct 22 01:49:04 2005 @@ -90,5 +90,6 @@ sim = SimGraph(self.nodes, FlowSimNode, self.calls) log.calltree('simulating...') sim.sim_all(0.9, 50) + # here I'm still playing around with parameters. import pdb pdb.set_trace() From pedronis at codespeak.net Sat Oct 22 02:26:34 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 22 Oct 2005 02:26:34 +0200 (CEST) Subject: [pypy-svn] r18835 - pypy/dist/pypy/interpreter Message-ID: <20051022002634.DF75427B7A@code1.codespeak.net> Author: pedronis Date: Sat Oct 22 02:26:33 2005 New Revision: 18835 Modified: pypy/dist/pypy/interpreter/nestedscope.py Log: annotation issue Modified: pypy/dist/pypy/interpreter/nestedscope.py ============================================================================== --- pypy/dist/pypy/interpreter/nestedscope.py (original) +++ pypy/dist/pypy/interpreter/nestedscope.py Sat Oct 22 02:26:33 2005 @@ -170,7 +170,12 @@ assert isinstance(codeobj, pycode.PyCode) if codeobj.magic >= 0xa0df281: # CPython 2.5 AST branch merge w_freevarstuple = f.valuestack.pop() - freevars = f.space.unpacktuple(w_freevarstuple) + freevars = [] + for cell in f.space.unpacktuple(w_freevarstuple): + cell = f.space.interpclass_w(cell) + if not isinstance(cell, Cell): + raise pyframe.BytecodeCorruption + freevars.append(cell) else: nfreevars = len(codeobj.co_freevars) freevars = [] From sanxiyn at codespeak.net Sat Oct 22 05:51:46 2005 From: sanxiyn at codespeak.net (sanxiyn at codespeak.net) Date: Sat, 22 Oct 2005 05:51:46 +0200 (CEST) Subject: [pypy-svn] r18836 - pypy/dist/pypy/translator/pyrex/Pyrex/Compiler Message-ID: <20051022035146.B35A827B86@code1.codespeak.net> Author: sanxiyn Date: Sat Oct 22 05:51:41 2005 New Revision: 18836 Modified: pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Code.py pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/ExprNodes.py pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Nodes.py Log: Adapt Pyrex 0.9.3.1 patches to be compatible with GCC 4. This fixes GCC error "invalid lvalue in assignment". Modified: pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Code.py ============================================================================== --- pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Code.py (original) +++ pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Code.py Sat Oct 22 05:51:41 2005 @@ -218,14 +218,16 @@ for entry in entries: self.put_var_xdecref_clear(entry) - def put_init_to_py_none(self, cname): - self.putln("%s = Py_None; Py_INCREF(%s);" % (cname, cname)) + def put_init_to_py_none(self, cast, cname): + if cast: + self.putln("%s = (void *)Py_None; Py_INCREF((PyObject *)%s);" % (cname, cname)) + else: + self.putln("%s = Py_None; Py_INCREF(%s);" % (cname, cname)) def put_init_var_to_py_none(self, entry, template = "%s"): code = template % entry.cname - if entry.type.is_extension_type: - code = "((PyObject*)%s)" % code - self.put_init_to_py_none(code) + cast = entry.type.is_extension_type + self.put_init_to_py_none(cast, code) def put_pymethoddef(self, entry, term): if entry.doc: Modified: pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/ExprNodes.py ============================================================================== --- pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/ExprNodes.py (original) +++ pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/ExprNodes.py Sat Oct 22 05:51:41 2005 @@ -806,7 +806,7 @@ if self.type.is_pyobject: rhs.make_owned_reference(code) code.put_decref(self.result, self.type) - code.putln('%s = %s;' % (self.result, rhs.result)) + code.putln('%s = %s;' % (self.entry.cname, rhs.result)) if debug_disposal_code: print "NameNode.generate_assignment_code:" print "...generating post-assignment code for", rhs Modified: pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Nodes.py ============================================================================== --- pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Nodes.py (original) +++ pypy/dist/pypy/translator/pyrex/Pyrex/Compiler/Nodes.py Sat Oct 22 05:51:41 2005 @@ -1684,11 +1684,9 @@ # ----- Default return value code.putln("") if self.return_type.is_pyobject: - if self.return_type.is_extension_type: - lhs = "(PyObject *)%s" % Naming.retval_cname - else: - lhs = Naming.retval_cname - code.put_init_to_py_none(lhs) + cast = self.return_type.is_extension_type + lhs = Naming.retval_cname + code.put_init_to_py_none(cast, lhs) else: val = self.return_type.default_value if val: From afa at codespeak.net Sat Oct 22 21:11:19 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Sat, 22 Oct 2005 21:11:19 +0200 (CEST) Subject: [pypy-svn] r18837 - in pypy/dist/pypy: module/_socket/rpython module/_socket/rpython/test translator/c translator/c/src translator/c/test Message-ID: <20051022191119.6377627B9E@code1.codespeak.net> Author: afa Date: Sat Oct 22 21:11:07 2005 New Revision: 18837 Modified: pypy/dist/pypy/module/_socket/rpython/exttable.py pypy/dist/pypy/module/_socket/rpython/ll__socket.py pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll__socket.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Translation of socket.gethostname() The exception raised is wrong - but it is difficult to make gethostname return an error. Will test with another function. Modified: pypy/dist/pypy/module/_socket/rpython/exttable.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/exttable.py (original) +++ pypy/dist/pypy/module/_socket/rpython/exttable.py Sat Oct 22 21:11:07 2005 @@ -10,6 +10,8 @@ # ____________________________________________________________ # Built-in functions needed in the rtyper +declare(_socket.gethostname, str, '%s/gethostname' % module) + declare(_socket.ntohs, int, '%s/ntohs' % module) declare(_socket.htons, int, '%s/ntohs' % module) declare(_socket.ntohl, int, '%s/ntohl' % module) Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Sat Oct 22 21:11:07 2005 @@ -1,5 +1,11 @@ import _socket +from pypy.rpython.module.support import to_rstr + +def ll__socket_gethostname(): + return to_rstr(_socket.gethostname()) +ll__socket_gethostname.suggested_primitive = True + def ll__socket_ntohs(htons): return _socket.ntohs(htons) ll__socket_ntohs.suggested_primitive = True @@ -15,3 +21,4 @@ def ll__socket_ntohl(htonl): return _socket.ntohl(htonl) ll__socket_ntohl.suggested_primitive = True + Modified: pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py Sat Oct 22 21:11:07 2005 @@ -4,6 +4,7 @@ from pypy.module._socket.rpython.ll__socket import * from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython.test.test_llinterp import interpret +from pypy.rpython.module.support import from_rstr def test_ntohs(): def fn(): @@ -11,3 +12,10 @@ a = RPythonAnnotator() res = interpret(fn, []) assert res == _socket.ntohs(1) + +def test_gethostname(): + def fn(): + return _socket.gethostname() + a = RPythonAnnotator() + res = interpret(fn, []) + assert from_rstr(res) == _socket.gethostname() Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Sat Oct 22 21:11:07 2005 @@ -57,6 +57,7 @@ ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', ll_stack.ll_stack_unwind: 'LL_stack_unwind', ll_stack.ll_stack_too_big: 'LL_stack_too_big', + ll__socket.ll__socket_gethostname: 'LL__socket_gethostname', ll__socket.ll__socket_ntohs: 'LL__socket_ntohs', ll__socket.ll__socket_htons: 'LL__socket_htons', ll__socket.ll__socket_htonl: 'LL__socket_htonl', Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Sat Oct 22 21:11:07 2005 @@ -40,4 +40,20 @@ } +RPyString *LL__socket_gethostname() +{ + char buf[1024]; + char *res; + res = gethostname(buf, sizeof buf - 1); + if (res < 0) { + //XXX + //RPYTHON_RAISE_OSERROR(errno); + RPyRaiseSimpleException(PyExc_ValueError, + "gethostname() error"); + return NULL; + } + buf[sizeof buf - 1] = '\0'; + return RPyString_FromString(buf); +} + #endif 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 Sat Oct 22 21:11:07 2005 @@ -1,6 +1,6 @@ import autopath import py -import os, time, sys +import os, time, sys, _socket from pypy.tool.udir import udir from pypy.translator.c.test.test_genc import compile from pypy.translator.c.extfunc import EXTERNALS @@ -532,8 +532,7 @@ compared_with.sort() assert result == compared_with -def test_socket(): - import _socket +def test_htonl(): import pypy.module._socket.rpython.exttable # for declare()/declaretype() # This just checks that htons etc. are their own inverse, # when looking at the lower 16 or 32 bits. @@ -552,4 +551,14 @@ # Don't try with 'long' values: type conversion is done # at the interp level, not at the C level for i in (0, 1, 0xffff, 2, 0x01234567, 0x76543210): + print func, hex(i&mask) assert i & mask == func(func(i&mask)) & mask + +def test_gethostname(): + import pypy.module._socket.rpython.exttable # for declare()/declaretype() + def does_stuff(): + return _socket.gethostname() + f1 = compile(does_stuff, []) + res = f1() + assert res == _socket.gethostname() + From pedronis at codespeak.net Sat Oct 22 23:11:09 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 22 Oct 2005 23:11:09 +0200 (CEST) Subject: [pypy-svn] r18838 - in pypy/dist/pypy: annotation rpython rpython/lltypesystem rpython/test translator Message-ID: <20051022211109.785CA27B96@code1.codespeak.net> Author: pedronis Date: Sat Oct 22 23:11:04 2005 New Revision: 18838 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/model.py pypy/dist/pypy/annotation/unaryop.py pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rptr.py pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/rpython/test/test_lltype.py pypy/dist/pypy/rpython/test/test_rdict.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/rpython/test/test_rptr.py pypy/dist/pypy/translator/transform.py Log: * type erasure for lists * doing that discovered a bug in the rtyper logic for splitting a llops block when the operation that can raise an exception is in the middle * support for attaching methods (ADT meths) to ll container types, should make the code for supporting fixed size list in the rtyper reasonable: if l is some kind of list it should be now possible to express generalized access to items or length as l.ll_items() and l.ll_length(), this get trasforment into normal ll function calls (doing the latter it has become clear that the call logic in bookkeeper need some refactoring, not clear when we can get to it) Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Sat Oct 22 23:11:04 2005 @@ -487,6 +487,8 @@ return s_result + # xxx refactor + def consider_pbc_call(self, pbc, shape, spaceop=None, implicit_init=None): # computation done at fix-point if not isinstance(pbc, SomePBC): return @@ -602,22 +604,27 @@ else: s_obj, init_classdef = implicit_init - assert isinstance(s_obj, SomePBC) - if len(s_obj.prebuiltinstances) > 1: # no specialization expected - return s_obj, False - argsvars = spaceop.args[1:] args_s = [self.annotator.binding(v) for v in argsvars] args = self.build_args(spaceop.opname, args_s) - func, classdef = s_obj.prebuiltinstances.items()[0] + if isinstance(s_obj, SomePBC): + if len(s_obj.prebuiltinstances) > 1: # no specialization expected + return s_obj, False + + func, classdef = s_obj.prebuiltinstances.items()[0] + + if init_classdef: + args = args.prepend(SomeInstance(init_classdef)) + elif isclassdef(classdef): + s_self = SomeInstance(classdef) + args = args.prepend(s_self) + elif isinstance(s_obj, SomeLLADTMeth): + func = s_obj.func + args = args.prepend(SomePtr(s_obj.ll_ptrtype)) + else: + assert False, "unexpected callable %r for query_spaceop_callable" % s_obj - if init_classdef: - args = args.prepend(SomeInstance(init_classdef)) - elif isclassdef(classdef): - s_self = SomeInstance(classdef) - args = args.prepend(s_self) - func, key = decide_callable(self, spaceop, func, args, mono=True) if key is None: @@ -626,7 +633,10 @@ if func is None: # specialisation computes annotation direclty return s_obj, True - return SomePBC({func: classdef}), False + if isinstance(s_obj, SomePBC): + return SomePBC({func: classdef}), False + else: + return SomeLLADTMeth(s_obj.ll_ptrtype, func), False finally: self.leave() Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Sat Oct 22 23:11:04 2005 @@ -431,6 +431,14 @@ def can_be_none(self): return False +class SomeLLADTMeth(SomeObject): + def __init__(self, ll_ptrtype, func): + self.ll_ptrtype = ll_ptrtype + self.func = func + + def can_be_none(self): + return False + class SomeOOClass(SomeObject): def __init__(self, ootype): self.ootype = ootype @@ -495,6 +503,10 @@ # functions from bookkeeper import getbookkeeper return getbookkeeper().immutablevalue(None) + if isinstance(v, MethodType): + ll_ptrtype = lltype.typeOf(v.im_self) + assert isinstance(ll_ptrtype, lltype.Ptr) + return SomeLLADTMeth(ll_ptrtype, v.im_func) return lltype_to_annotation(lltype.typeOf(v)) # ____________________________________________________________ Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Sat Oct 22 23:11:04 2005 @@ -566,7 +566,8 @@ # annotation of low-level types -from pypy.annotation.model import SomePtr, SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth +from pypy.annotation.model import SomePtr, SomeLLADTMeth +from pypy.annotation.model import SomeOOInstance, SomeOOBoundMeth, SomeOOStaticMeth from pypy.annotation.model import ll_to_annotation, annotation_to_lltype class __extend__(SomePtr): @@ -594,6 +595,12 @@ def is_true(p): return SomeBool() +class __extend__(SomeLLADTMeth): + + def call(adtmeth, args): + bookkeeper = getbookkeeper() + return bookkeeper.pycall(adtmeth.func, args.prepend(SomePtr(adtmeth.ll_ptrtype)), mono=True) + from pypy.rpython.ootypesystem import ootype class __extend__(SomeOOInstance): def getattr(r, s_attr): Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sat Oct 22 23:11:04 2005 @@ -116,17 +116,32 @@ def _is_varsize(self): return False +NFOUND = object() class ContainerType(LowLevelType): + _adtmeths = {} + def _gcstatus(self): return isinstance(self, GC_CONTAINER) def _inline_is_varsize(self, last): raise TypeError, "%r cannot be inlined in structure" % self + def _install_adtmeths(self, adtmeths={}): + self._adtmeths = frozendict(adtmeths) + + def __getattr__(self, name): + adtmeth = self._adtmeths.get(name, NFOUND) + if adtmeth is not NFOUND: + return adtmeth + self._nofield(name) + + def _nofield(self, name): + raise AttributeError("no field %r" % name) + class Struct(ContainerType): - def __init__(self, name, *fields): + def __init__(self, name, *fields, **kwds): self._name = self.__name__ = name flds = {} names = [] @@ -157,6 +172,8 @@ self._flds = frozendict(flds) self._names = tuple(names) + self._install_adtmeths(**kwds) + def _first_struct(self): if self._names: first = self._names[0] @@ -184,8 +201,12 @@ try: return self._flds[name] except KeyError: - raise AttributeError, 'struct %s has no field %r' % (self._name, - name) + return ContainerType.__getattr__(self, name) + + + def _nofield(self, name): + raise AttributeError, 'struct %s has no field %r' % (self._name, + name) def _names_without_voids(self): names_without_voids = [name for name in self._names if self._flds[name] is not Void] @@ -243,7 +264,7 @@ __name__ = 'array' _anonym_struct = False - def __init__(self, *fields): + def __init__(self, *fields, **kwds): if len(fields) == 1 and isinstance(fields[0], LowLevelType): self.OF = fields[0] else: @@ -253,6 +274,8 @@ raise TypeError("cannot have a GC structure as array item type") self.OF._inline_is_varsize(False) + self._install_adtmeths(**kwds) + def _inline_is_varsize(self, last): if not last: raise TypeError("cannot inline an array in another container" @@ -611,6 +634,10 @@ if field_name in self._T._flds: o = getattr(self._obj, field_name) return _expose(o) + if isinstance(self._T, ContainerType): + adtmeth = self._T._adtmeths.get(field_name) + if adtmeth is not None: + return adtmeth.__get__(self) raise AttributeError("%r instance has no field %r" % (self._T, field_name)) Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Sat Oct 22 23:11:04 2005 @@ -593,9 +593,15 @@ r.item1 = entry.value items[p] = r elif func is dum_keys: - items[p] = entry.key + k = entry.key + if isinstance(LISTPTR.TO.items.TO.OF, lltype.Ptr): + k = lltype.cast_pointer(LISTPTR.TO.items.TO.OF, k) + items[p] = k elif func is dum_values: - items[p] = entry.value + val = entry.value + if isinstance(LISTPTR.TO.items.TO.OF, lltype.Ptr): + val = lltype.cast_pointer(LISTPTR.TO.items.TO.OF, val) + items[p] = val p += 1 i += 1 return res Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Sat Oct 22 23:11:04 2005 @@ -37,7 +37,7 @@ else: # cannot do the rtyper.getrepr() call immediately, for the case # of recursive structures -- i.e. if the listdef contains itself - return ListRepr(lambda: rtyper.getrepr(listitem.s_value), + return ListRepr(rtyper, lambda: rtyper.getrepr(listitem.s_value), listitem) def rtyper_makekey(self): @@ -46,21 +46,33 @@ class ListRepr(Repr): - def __init__(self, item_repr, listitem=None): + def __init__(self, rtyper, item_repr, listitem=None): + self.rtyper = rtyper self.LIST = GcForwardReference() self.lowleveltype = Ptr(self.LIST) if not isinstance(item_repr, Repr): # not computed yet, done by setup() assert callable(item_repr) self._item_repr_computer = item_repr else: - self.item_repr = item_repr + self.set_item_repr(item_repr) self.listitem = listitem self.list_cache = {} # setup() needs to be called to finish this initialization + def set_item_repr(self, item_repr): + from pypy.rpython import rclass + if isinstance(item_repr, rclass.AbstractInstanceRepr): + self.item_repr = rclass.getinstancerepr(self.rtyper, None) + self.external_item_repr = item_repr + else: + self.item_repr = self.external_item_repr = item_repr + + def recast(self, llops, v): + return llops.convertvar(v, self.item_repr, self.external_item_repr) + def _setup_repr(self): if 'item_repr' not in self.__dict__: - self.item_repr = self._item_repr_computer() + self.set_item_repr(self._item_repr_computer()) if isinstance(self.LIST, GcForwardReference): ITEM = self.item_repr.lowleveltype ITEMARRAY = GcArray(ITEM) @@ -164,7 +176,8 @@ args = hop.inputargs(self) llfn = ll_pop_default hop.exception_is_here() - return hop.gendirectcall(llfn, v_func, *args) + v_res = hop.gendirectcall(llfn, v_func, *args) + return self.recast(hop.llops, v_res) def make_iterator_repr(self): return ListIteratorRepr(self) @@ -209,7 +222,8 @@ else: llfn = ll_getitem hop.exception_is_here() - return hop.gendirectcall(llfn, v_func, v_lst, v_index) + v_res = hop.gendirectcall(llfn, v_func, v_lst, v_index) + return r_lst.recast(hop.llops, v_res) def rtype_setitem((r_lst, r_int), hop): if hop.has_implicit_exception(IndexError): @@ -843,7 +857,8 @@ 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) + v_res = hop.gendirectcall(ll_listnext, v_iter) + return self.r_list.recast(hop.llops, v_res) def ll_listiter(ITERPTR, lst): iter = malloc(ITERPTR.TO) Modified: pypy/dist/pypy/rpython/rptr.py ============================================================================== --- pypy/dist/pypy/rpython/rptr.py (original) +++ pypy/dist/pypy/rpython/rptr.py Sat Oct 22 23:11:04 2005 @@ -1,7 +1,8 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel +from pypy.objspace.flow import model as flowmodel from pypy.rpython.lltype import Ptr, _ptr -from pypy.rpython.lltype import ContainerType, Void, Signed, Bool, FuncType +from pypy.rpython.lltype import ContainerType, Void, Signed, Bool, FuncType, typeOf from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst @@ -26,6 +27,8 @@ def rtype_getattr(self, hop): attr = hop.args_s[1].const + if isinstance(hop.s_result, annmodel.SomeLLADTMeth): + return hop.inputarg(hop.r_result, arg=0) FIELD_TYPE = getattr(self.lowleveltype.TO, attr) if isinstance(FIELD_TYPE, ContainerType): newopname = 'getsubstruct' @@ -121,3 +124,35 @@ def rtype_ne((r_any, r_ptr), hop): vlist = hop.inputargs(r_ptr, r_ptr) return hop.genop('ptr_ne', vlist, resulttype=Bool) + +# ________________________________________________________________ +# ADT methods + +class __extend__(annmodel.SomeLLADTMeth): + def rtyper_makerepr(self, rtyper): + return LLADTMethRepr(self) + def rtyper_makekey(self): + return self.__class__, self.ll_ptrtype, self.func + +class LLADTMethRepr(Repr): + + def __init__(self, adtmeth): + self.adtmeth = adtmeth + self.lowleveltype = adtmeth.ll_ptrtype + + def rtype_hardwired_simple_call(self, hop): + hop2 = hop.copy() + hop2.swap_fst_snd_args() + r_func, s_func = hop2.r_s_popfirstarg() + fptr = hop2.rtyper.getcallable(s_func.const) + hop2.v_s_insertfirstarg(flowmodel.Constant(fptr), annmodel.SomePtr(typeOf(fptr))) + return hop2.dispatch(opname='simple_call') + +class __extend__(pairtype(PtrRepr, LLADTMethRepr)): + + def convert_from_to((r_from, r_to), v, llops): + if r_from.lowleveltype == r_to.lowleveltype: + return v + return NotImplemented + + Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Sat Oct 22 23:11:04 2005 @@ -156,6 +156,11 @@ self.exceptiondata.make_helpers(self) self.specialize_more_blocks() # for the helpers just made + # + from pypy.annotation import listdef + ldef = listdef.ListDef(None, annmodel.SomeString()) + self.list_of_str_repr = self.getrepr(annmodel.SomeList(ldef)) + def specialize_more_blocks(self): while True: # look for blocks not specialized yet @@ -300,6 +305,7 @@ block.operations[:] = newops block.renamevariables(varmapping) + extrablock = None 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 @@ -322,16 +328,24 @@ 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) + extrablock = insert_empty_block(self.annotator.translator, + noexclink, + newops = extraops) - self.insert_link_conversions(block) + if extrablock is None: + self.insert_link_conversions(block) + else: + # skip the extrablock as a link target, its link doesn't need conversions + # by construction, OTOH some of involved vars have no annotation + # so proceeding with it would kill information + self.insert_link_conversions(block, skip=1) + # consider it as a link source instead + self.insert_link_conversions(extrablock) - def insert_link_conversions(self, block): + def insert_link_conversions(self, block, skip=0): # insert the needed conversions on the links can_insert_here = block.exitswitch is None and len(block.exits) == 1 - for link in block.exits: + for link in block.exits[skip:]: if link.exitcase is not None: if isinstance(block.exitswitch, Variable): r_case = self.bindingrepr(block.exitswitch) 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 Sat Oct 22 23:11:04 2005 @@ -424,3 +424,32 @@ assert Q._is_atomic() is False assert O._is_atomic() is False assert F._is_atomic() is False + +def test_adtmeths(): + def h_newstruct(): + return malloc(S) + + S = GcStruct('s', ('x', Signed), + adtmeths={"h_newstruct": h_newstruct}) + + s = S.h_newstruct() + + assert typeOf(s) == Ptr(S) + + def h_alloc(n): + return malloc(A, n) + + def h_length(a): + return len(a) + + A = GcArray(Signed, + adtmeths={"h_alloc": h_alloc, + "h_length": h_length}) + + a = A.h_alloc(10) + + assert typeOf(a) == Ptr(A) + assert len(a) == 10 + + assert a.h_length() == 10 + Modified: pypy/dist/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rdict.py Sat Oct 22 23:11:04 2005 @@ -271,6 +271,16 @@ res = interpret(func, ())#, view=True) assert res == 14 +def test_dict_inst_keys(): + class A: + pass + def func(): + dic = {A(): 1, A(): 2} + keys = dic.keys() + return (isinstance(keys[1], A))*2+(isinstance(keys[0],A)) + res = interpret(func, []) + assert res == 3 + def test_dict_values(): def func(): dic = {' 4':1000, ' 8':200} @@ -279,6 +289,17 @@ res = interpret(func, ()) assert res == 1202 +def test_dict_inst_value(): + class A: + pass + def func(): + dic = {1: A(), 2: A()} + vals = dic.values() + return (isinstance(vals[1], A))*2+(isinstance(vals[0],A)) + res = interpret(func, []) + assert res == 3 + + def test_dict_items(): def func(): dic = {' 4':1000, ' 8':200} 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 Sat Oct 22 23:11:04 2005 @@ -19,7 +19,7 @@ del n1, n2, name def sample_list(): # [42, 43, 44, 45] - rlist = ListRepr(signed_repr) + rlist = ListRepr(None, signed_repr) rlist.setup() l = ll_newlist(rlist.lowleveltype, 3) ll_setitem(l, 0, 42) @@ -204,6 +204,19 @@ res = interpret(dummyfn, ())#, view=True) assert res == 42 +def test_inst_pop(): + class A: + pass + l = [A(), A()] + def f(idx): + try: + return l.pop(idx) + except IndexError: + return None + res = interpret(f, [1]) + assert ''.join(res.super.typeptr.name) == 'A\00' + + def test_reverse(): def dummyfn(): l = [5, 3, 2] @@ -375,6 +388,23 @@ res = interpret(fn, [2]) assert res == 1 +def test_inst_list(): + def fn(): + l = [None] + l[0] = Foo() + l.append(Bar()) + l2 = [l[1], l[0], l[0]] + l.extend(l2) + for x in l2: + l.append(x) + x = l.pop() + x = l.pop() + x = l.pop() + x = l2.pop() + return str(x)+";"+str(l) + res = interpret(fn, []) + assert ''.join(res.chars) == ';[, , , , ]' + def test_list_slice_minusone(): def fn(i): lst = [i, i+1, i+2] Modified: pypy/dist/pypy/rpython/test/test_rptr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rptr.py (original) +++ pypy/dist/pypy/rpython/test/test_rptr.py Sat Oct 22 23:11:04 2005 @@ -1,5 +1,5 @@ from pypy.translator.annrpython import RPythonAnnotator -from pypy.rpython.annlowlevel import annotate_lowlevel_helper +from pypy.rpython.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy from pypy.rpython.lltype import * from pypy.rpython.rtyper import RPythonTyper from pypy.annotation import model as annmodel @@ -43,3 +43,52 @@ s, t = ll_rtype(ll_example, [annmodel.SomePtr(Ptr(S))]) assert s == annmodel.SomeTuple([annmodel.SomePtr(Ptr(RuntimeTypeInfo)), annmodel.SomeBool()]) + +from pypy.rpython.test.test_llinterp import interpret, gengraph + +def test_adtmeths(): + policy = LowLevelAnnotatorPolicy() + + def h_newstruct(): + return malloc(S) + + S = GcStruct('s', ('x', Signed), + adtmeths={"h_newstruct": h_newstruct}) + + def f(): + return S.h_newstruct() + + s = interpret(f, [], policy=policy) + + assert typeOf(s) == Ptr(S) + + def h_alloc(n): + return malloc(A, n) + def h_length(a): + return len(a) + + A = GcArray(Signed, + adtmeths={"h_alloc": h_alloc, + "h_length": h_length, + 'flag': True}) + + def f(): + return A.h_alloc(10) + + a = interpret(f, [], policy=policy) + + assert typeOf(a) == Ptr(A) + assert len(a) == 10 + + + def f(): + a = A.h_alloc(10) + return a.h_length() + + res = interpret(f, [], policy=policy) + assert res == 10 + + def f(): + return A.flag + res = interpret(f, [], policy=policy) + assert res Modified: pypy/dist/pypy/translator/transform.py ============================================================================== --- pypy/dist/pypy/translator/transform.py (original) +++ pypy/dist/pypy/translator/transform.py Sat Oct 22 23:11:04 2005 @@ -186,6 +186,12 @@ op.args[0] = Constant(memo_table) else: op.opname = intern('call_specialcase') + elif isinstance(callb, annmodel.SomeLLADTMeth): + specialized_callb, specialcase = self.bookkeeper.query_spaceop_callable(op) + assert not specialcase + assert not isinstance(op.args[0], Constant) and not callb.is_constant() + op.opname = intern('hardwired_'+op.opname) + op.args.insert(1, Constant(specialized_callb.func)) def insert_stackcheck(ann): from pypy.tool.algo.graphlib import Edge, make_edge_dict, break_cycles From tismer at codespeak.net Sun Oct 23 14:16:03 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 23 Oct 2005 14:16:03 +0200 (CEST) Subject: [pypy-svn] r18843 - in pypy/dist/pypy: rpython translator/c/src Message-ID: <20051023121603.DA37A27B76@code1.codespeak.net> Author: tismer Date: Sun Oct 23 14:16:02 2005 New Revision: 18843 Modified: pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/translator/c/src/ll_os.h Log: small typos the real reason why I'm looking into this is that the windows version is way not that easy as Armin thought :-) Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Sun Oct 23 14:16:02 2005 @@ -1,5 +1,5 @@ """ -information table about external functions for annotation/ rtyping and backends +information table about external functions for annotation/rtyping and backends """ import os import 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 Sun Oct 23 14:16:02 2005 @@ -257,7 +257,7 @@ #endif /* Return a dictionary corresponding to the POSIX environment table */ -/*** actually, we create a sring list here and do the rest in posix */ +/*** actually, we create a string 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(). From tismer at codespeak.net Sun Oct 23 19:54:00 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 23 Oct 2005 19:54:00 +0200 (CEST) Subject: [pypy-svn] r18844 - pypy/dist/pypy/translator/c/src Message-ID: <20051023175400.66CF927B82@code1.codespeak.net> Author: tismer Date: Sun Oct 23 19:53:58 2005 New Revision: 18844 Added: pypy/dist/pypy/translator/c/src/ll_osdefs.h (contents, props changed) Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: added support for os.listdir() for windows. Unfortunately, the opendir/readdir/closedir interface does not fit perfectly, so I wrote these functions in ll_os.h. Not sure whether it is worth rewriting the interface to be able to express this windows-specific stuff from higher levels. * implemented opendir, readdir, closedir in C * extracted the bulk of definitions from posixmodule.c into ll_osdefs.h Comments are welcome. Anyway, things compile under Windows, again :-) 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 Sun Oct 23 19:53:58 2005 @@ -66,6 +66,8 @@ #ifndef PYPY_NOT_MAIN_FILE +#include "ll_osdefs.h" + int LL_os_open(RPyString *filename, int flag, int mode) { /* XXX unicode_file_names */ @@ -223,7 +225,12 @@ } void LL_os_mkdir(RPyString * path, int mode) { +#if defined(MS_WIN64) || defined(MS_WINDOWS) + /* no mode support on Windows */ + int error = mkdir(RPyString_AsString(path)); +#else int error = mkdir(RPyString_AsString(path), mode); +#endif if (error != 0) { RPYTHON_RAISE_OSERROR(errno); } @@ -283,52 +290,118 @@ /******************** opendir/readdir/closedir ********************/ -#ifdef HAVE_DIRENT_H -#include -#define NAMLEN(dirent) strlen((dirent)->d_name) -#else -#if defined(__WATCOMC__) && !defined(__QNX__) -#include -#define NAMLEN(dirent) strlen((dirent)->d_name) -#else -#define dirent direct -#define NAMLEN(dirent) (dirent)->d_namlen -#endif -#ifdef HAVE_SYS_NDIR_H -#include -#endif -#ifdef HAVE_SYS_DIR_H -#include -#endif -#ifdef HAVE_NDIR_H -#include -#endif -#endif +#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) + +/* emulation of opendir, readdir, closedir */ + +/* + the problem is that Windows does not have something like + opendir. Instead, FindFirstFile creates a handle and + yields the first entry found. Furthermore, we need + to mangle the filename. + To keep the rpython interface, we need to buffer the + first result and let readdir return this first time. + Drawback of this approach: we need to use malloc, + and the way I'm emulating dirent is maybe somewhat hackish. + + XXX we are lacking unicode support, completely. + Might need a different interface. + */ + +#undef dirent + +typedef struct dirent { + HANDLE hFind; + WIN32_FIND_DATA FileData; + char *d_name; /* faking dirent */ + int first_done; +} DIR; + +static DIR *opendir(char *dirname) +{ + DIR *d = malloc(sizeof(DIR)); + int lng = strlen(dirname); + char *mangled = strcpy(_alloca(lng + 5), dirname); + char *p = mangled + lng; + + if (d == NULL) + return NULL; + + if (lng && p[-1] == '\\') + p--; + strcpy(p, "\\*.*"); + + d->first_done = 0; + d->hFind = FindFirstFile(mangled, &d->FileData); + if (d->hFind == INVALID_HANDLE_VALUE) { + d->d_name = NULL; + errno = GetLastError(); + if (errno == ERROR_FILE_NOT_FOUND) { + errno = 0; + return d; + } + free(d); + return NULL; + } + d->d_name = d->FileData.cFileName; + return d; +} + +static struct dirent *readdir(DIR *d) +{ + if (!d->first_done) { + d->first_done = 1; + return d; + } + if (!FindNextFile(d->hFind, &d->FileData)) + { + errno = GetLastError(); + if (errno == ERROR_NO_MORE_FILES) + errno = 0; + return NULL; + } + d->d_name = d->FileData.cFileName; + return d; +} + +static int closedir(DIR *d) +{ + HANDLE hFind = d->hFind; + + free(d); + if (FindClose(hFind) == 0) { + errno = GetLastError(); + return -1; + } + return 0; +} + +#endif /* defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) */ struct RPyOpaque_DIR *LL_os_opendir(RPyString *dirname) { - DIR *dir = opendir(RPyString_AsString(dirname)); - if (dir == NULL) - RPYTHON_RAISE_OSERROR(errno); - return (struct RPyOpaque_DIR *) dir; + DIR *dir = opendir(RPyString_AsString(dirname)); + if (dir == NULL) + RPYTHON_RAISE_OSERROR(errno); + return (struct RPyOpaque_DIR *) dir; } RPyString *LL_os_readdir(struct RPyOpaque_DIR *dir) { - struct dirent *d; - errno = 0; - d = readdir((DIR *) dir); - if (d != NULL) - return RPyString_FromString(d->d_name); - if (errno) - RPYTHON_RAISE_OSERROR(errno); - return NULL; + struct dirent *d; + errno = 0; + d = readdir((DIR *) dir); + if (d != NULL) + return RPyString_FromString(d->d_name); + if (errno) + RPYTHON_RAISE_OSERROR(errno); + return NULL; } void LL_os_closedir(struct RPyOpaque_DIR *dir) { - if (closedir((DIR *) dir) < 0) - RPYTHON_RAISE_OSERROR(errno); + if (closedir((DIR *) dir) < 0) + RPYTHON_RAISE_OSERROR(errno); } #endif /* PYPY_NOT_MAIN_FILE */ Added: pypy/dist/pypy/translator/c/src/ll_osdefs.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/ll_osdefs.h Sun Oct 23 19:53:58 2005 @@ -0,0 +1,282 @@ +/************************************************************/ + /*** C header subsection: definition part extracted + from posixmodule.c ***/ + +/* this file is only meant to be included by ll_os.h */ + +#if defined(PYOS_OS2) +#define INCL_DOS +#define INCL_DOSERRORS +#define INCL_DOSPROCESS +#define INCL_NOPMAPI +#include +#if defined(PYCC_GCC) +#include +#include +#include +#include +#endif +#include "osdefs.h" +#endif + +#include +#include + +#ifdef HAVE_SYS_WAIT_H +#include /* For WNOHANG */ +#endif + +#include + +#ifdef HAVE_FCNTL_H +#include +#endif /* HAVE_FCNTL_H */ + +#ifdef HAVE_GRP_H +#include +#endif + +#ifdef HAVE_SYSEXITS_H +#include +#endif /* HAVE_SYSEXITS_H */ + +#ifdef HAVE_SYS_LOADAVG_H +#include +#endif + +/* Various compilers have only certain posix functions */ +/* XXX Gosh I wish these were all moved into pyconfig.h */ +#if defined(PYCC_VACPP) && defined(PYOS_OS2) +#include +#else +#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */ +#define HAVE_GETCWD 1 +#define HAVE_OPENDIR 1 +#define HAVE_SYSTEM 1 +#if defined(__OS2__) +#define HAVE_EXECV 1 +#define HAVE_WAIT 1 +#endif +#include +#else +#ifdef __BORLANDC__ /* Borland compiler */ +#define HAVE_EXECV 1 +#define HAVE_GETCWD 1 +#define HAVE_OPENDIR 1 +#define HAVE_PIPE 1 +#define HAVE_POPEN 1 +#define HAVE_SYSTEM 1 +#define HAVE_WAIT 1 +#else +#ifdef _MSC_VER /* Microsoft compiler */ +#define HAVE_GETCWD 1 +#define HAVE_SPAWNV 1 +#define HAVE_EXECV 1 +#define HAVE_PIPE 1 +#define HAVE_POPEN 1 +#define HAVE_SYSTEM 1 +#define HAVE_CWAIT 1 +#define HAVE_FSYNC 1 +#define fsync _commit +#else +#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS) +/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */ +#else /* all other compilers */ +/* Unix functions that the configure script doesn't check for */ +#define HAVE_EXECV 1 +#define HAVE_FORK 1 +#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */ +#define HAVE_FORK1 1 +#endif +#define HAVE_GETCWD 1 +#define HAVE_GETEGID 1 +#define HAVE_GETEUID 1 +#define HAVE_GETGID 1 +#define HAVE_GETPPID 1 +#define HAVE_GETUID 1 +#define HAVE_KILL 1 +#define HAVE_OPENDIR 1 +#define HAVE_PIPE 1 +#ifndef __rtems__ +#define HAVE_POPEN 1 +#endif +#define HAVE_SYSTEM 1 +#define HAVE_WAIT 1 +#define HAVE_TTYNAME 1 +#endif /* PYOS_OS2 && PYCC_GCC && __VMS */ +#endif /* _MSC_VER */ +#endif /* __BORLANDC__ */ +#endif /* ! __WATCOMC__ || __QNX__ */ +#endif /* ! __IBMC__ */ + +#ifndef _MSC_VER + +#if defined(__sgi)&&_COMPILER_VERSION>=700 +/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode + (default) */ +extern char *ctermid_r(char *); +#endif + +#ifndef HAVE_UNISTD_H +#if defined(PYCC_VACPP) +extern int mkdir(char *); +#else +#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__) +extern int mkdir(const char *); +#else +extern int mkdir(const char *, mode_t); +#endif +#endif +#if defined(__IBMC__) || defined(__IBMCPP__) +extern int chdir(char *); +extern int rmdir(char *); +#else +extern int chdir(const char *); +extern int rmdir(const char *); +#endif +#ifdef __BORLANDC__ +extern int chmod(const char *, int); +#else +extern int chmod(const char *, mode_t); +#endif +extern int chown(const char *, uid_t, gid_t); +extern char *getcwd(char *, int); +extern char *strerror(int); +extern int link(const char *, const char *); +extern int rename(const char *, const char *); +extern int stat(const char *, struct stat *); +extern int unlink(const char *); +extern int pclose(FILE *); +#ifdef HAVE_SYMLINK +extern int symlink(const char *, const char *); +#endif /* HAVE_SYMLINK */ +#ifdef HAVE_LSTAT +extern int lstat(const char *, struct stat *); +#endif /* HAVE_LSTAT */ +#endif /* !HAVE_UNISTD_H */ + +#endif /* !_MSC_VER */ + +#ifdef HAVE_UTIME_H +#include +#endif /* HAVE_UTIME_H */ + +#ifdef HAVE_SYS_UTIME_H +#include +#define HAVE_UTIME_H /* pretend we do for the rest of this file */ +#endif /* HAVE_SYS_UTIME_H */ + +#ifdef HAVE_SYS_TIMES_H +#include +#endif /* HAVE_SYS_TIMES_H */ + +#ifdef HAVE_SYS_PARAM_H +#include +#endif /* HAVE_SYS_PARAM_H */ + +#ifdef HAVE_SYS_UTSNAME_H +#include +#endif /* HAVE_SYS_UTSNAME_H */ + +#ifdef HAVE_DIRENT_H +#include +#define NAMLEN(dirent) strlen((dirent)->d_name) +#else +#if defined(__WATCOMC__) && !defined(__QNX__) +#include +#define NAMLEN(dirent) strlen((dirent)->d_name) +#else +#define dirent direct +#define NAMLEN(dirent) (dirent)->d_namlen +#endif +#ifdef HAVE_SYS_NDIR_H +#include +#endif +#ifdef HAVE_SYS_DIR_H +#include +#endif +#ifdef HAVE_NDIR_H +#include +#endif +#endif + +#ifdef _MSC_VER +#include +#include +#include +#include "osdefs.h" +#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */ +#include +#include /* for ShellExecute() */ +#define popen _popen +#define pclose _pclose +#endif /* _MSC_VER */ + +#if defined(PYCC_VACPP) && defined(PYOS_OS2) +#include +#endif /* OS2 */ + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif /* MAXPATHLEN */ + +#ifdef UNION_WAIT +/* Emulate some macros on systems that have a union instead of macros */ + +#ifndef WIFEXITED +#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump) +#endif + +#ifndef WEXITSTATUS +#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1) +#endif + +#ifndef WTERMSIG +#define WTERMSIG(u_wait) ((u_wait).w_termsig) +#endif + +#endif /* UNION_WAIT */ + +/* Don't use the "_r" form if we don't need it (also, won't have a + prototype for it, at least on Solaris -- maybe others as well?). */ +#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD) +#define USE_CTERMID_R +#endif + +#if defined(HAVE_TMPNAM_R) && defined(WITH_THREAD) +#define USE_TMPNAM_R +#endif + +/* choose the appropriate stat and fstat functions and return structs */ +#undef STAT +#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 + +#if defined(MAJOR_IN_MKDEV) +#include +#else +#if defined(MAJOR_IN_SYSMACROS) +#include +#endif +#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H) +#include +#endif +#endif + +/* Return a dictionary corresponding to the POSIX environment table */ +#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 */ From tismer at codespeak.net Sun Oct 23 20:20:25 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 23 Oct 2005 20:20:25 +0200 (CEST) Subject: [pypy-svn] r18845 - pypy/dist/pypy/translator/c/src Message-ID: <20051023182025.A53AA27B82@code1.codespeak.net> Author: tismer Date: Sun Oct 23 20:20:24 2005 New Revision: 18845 Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: removed definitions covered by ll_osdefs.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 Sun Oct 23 20:20:24 2005 @@ -265,15 +265,6 @@ /* Return a dictionary corresponding to the POSIX environment table */ /*** actually, we create a string 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; From pedronis at codespeak.net Sun Oct 23 22:08:39 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 23 Oct 2005 22:08:39 +0200 (CEST) Subject: [pypy-svn] r18848 - in pypy/dist/pypy: rpython rpython/lltypesystem rpython/test translator/c Message-ID: <20051023200839.AABC827B86@code1.codespeak.net> Author: pedronis Date: Sun Oct 23 22:08:36 2005 New Revision: 18848 Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rrange.py pypy/dist/pypy/rpython/rstr.py pypy/dist/pypy/rpython/rtuple.py pypy/dist/pypy/rpython/test/test_lltype.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/translator/c/extfunc.py Log: refactor rlist to use adt methods attached to the list GcStruct: .ll_items(), .ll_length() and .ll_newlist() respectively, in all code that could be shared by fixed/varsized lists. This should make implementing support for fixed size list fairly direct. Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sun Oct 23 22:08:36 2005 @@ -133,7 +133,10 @@ def __getattr__(self, name): adtmeth = self._adtmeths.get(name, NFOUND) if adtmeth is not NFOUND: - return adtmeth + if getattr(adtmeth, '_type_method', False): + return adtmeth.__get__(self) + else: + return adtmeth self._nofield(name) def _nofield(self, name): @@ -992,6 +995,12 @@ def isCompatibleType(TYPE1, TYPE2): return TYPE1 == TYPE2 + +# mark type ADT methods + +def typeMethod(func): + func._type_method = True + return func # FIXME __all__ = ['Array', 'Bool', 'Char', 'ContainerType', 'Float', @@ -1004,5 +1013,6 @@ 'castable', 'flavored_malloc', 'frozendict', 'functionptr', 'getRuntimeTypeInfo', 'log', 'malloc', 'nullptr', 'opaqueptr', 'operator', 'parentlink', 'py', 'pyobjectptr', 'r_uint', 'runtime_type_info', 'safe_equal', -'saferecursive', 'tlsobject', 'typeOf', 'weakref', 'isCompatibleType'] +'saferecursive', 'tlsobject', 'typeOf', 'weakref', 'isCompatibleType', +'typeMethod'] Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Sun Oct 23 22:08:36 2005 @@ -205,9 +205,9 @@ v_dic, = hop.inputargs(self) r_list = hop.r_result v_func = hop.inputconst(lltype.Void, spec) - c1 = hop.inputconst(lltype.Void, r_list.lowleveltype) + cLIST = hop.inputconst(lltype.Void, r_list.lowleveltype.TO) hop.exception_cannot_occur() - return hop.gendirectcall(ll_kvi, v_dic, c1, v_func) + return hop.gendirectcall(ll_kvi, v_dic, cLIST, v_func) def rtype_method_keys(self, hop): return self._rtype_method_kvi(hop, dum_keys) @@ -577,30 +577,30 @@ # note that by specialization on func, three different # and very efficient functions are created. -def ll_kvi(dic, LISTPTR, func): - res = rlist.ll_newlist(LISTPTR, dic.num_items) +def ll_kvi(dic, LIST, func): + res = LIST.ll_newlist(dic.num_items) dlen = len(dic.entries) entries = dic.entries - items = res.items + items = res.ll_items() i = 0 p = 0 while i < dlen: entry = entries[i] if entry.valid: if func is dum_items: - r = lltype.malloc(LISTPTR.TO.items.TO.OF.TO) + r = lltype.malloc(LIST.items.TO.OF.TO) r.item0 = entry.key r.item1 = entry.value items[p] = r elif func is dum_keys: k = entry.key - if isinstance(LISTPTR.TO.items.TO.OF, lltype.Ptr): - k = lltype.cast_pointer(LISTPTR.TO.items.TO.OF, k) + if isinstance(LIST.items.TO.OF, lltype.Ptr): + k = lltype.cast_pointer(LIST.items.TO.OF, k) items[p] = k elif func is dum_values: val = entry.value - if isinstance(LISTPTR.TO.items.TO.OF, lltype.Ptr): - val = lltype.cast_pointer(LISTPTR.TO.items.TO.OF, val) + if isinstance(LIST.items.TO.OF, lltype.Ptr): + val = lltype.cast_pointer(LIST.items.TO.OF, val) items[p] = val p += 1 i += 1 Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Sun Oct 23 22:08:36 2005 @@ -8,7 +8,7 @@ from pypy.rpython.rslice import minusone_slice_repr from pypy.rpython.lltype import GcForwardReference, Ptr, GcArray, GcStruct from pypy.rpython.lltype import Void, Signed, malloc, typeOf, Primitive -from pypy.rpython.lltype import Bool, nullptr +from pypy.rpython.lltype import Bool, nullptr, typeMethod from pypy.rpython import rstr from pypy.rpython import robject @@ -78,7 +78,13 @@ ITEMARRAY = GcArray(ITEM) # XXX we might think of turning length stuff into Unsigned self.LIST.become(GcStruct("list", ("length", Signed), - ("items", Ptr(ITEMARRAY)))) + ("items", Ptr(ITEMARRAY)), + adtmeths = { + "ll_newlist": ll_newlist, + "ll_length": ll_length, + "ll_items": ll_items, + }) + ) def compact_repr(self): return 'ListR %s' % (self.item_repr.compact_repr(),) @@ -110,7 +116,8 @@ def rtype_bltn_list(self, hop): v_lst = hop.inputarg(self, 0) - return hop.gendirectcall(ll_copy, v_lst) + cRESLIST = hop.inputconst(Void, hop.r_result.LIST) + return hop.gendirectcall(ll_copy, cRESLIST, v_lst) def rtype_len(self, hop): v_lst, = hop.inputargs(self) @@ -183,8 +190,8 @@ return ListIteratorRepr(self) def ll_str(self, l): - items = l.items - length = l.length + items = l.ll_items() + length = l.ll_length() item_repr = self.item_repr temp = malloc(TEMP, length) @@ -254,27 +261,27 @@ return hop.gendirectcall(llfn, v_func, v_lst, v_index) def rtype_mul((r_lst, r_int), hop): - v_func = hop.inputconst(Void, dum_newlist) + cRESLIST = hop.inputconst(Void, hop.r_result.LIST) v_lst, v_factor = hop.inputargs(r_lst, Signed) - return hop.gendirectcall(ll_mul, v_func, v_lst, v_factor) + return hop.gendirectcall(ll_mul, cRESLIST, v_lst, v_factor) def rtype_inplace_mul((r_lst, r_int), hop): - v_func = hop.inputconst(Void, dum_inplace) v_lst, v_factor = hop.inputargs(r_lst, Signed) - return hop.gendirectcall(ll_mul, v_func, v_lst, v_factor) + return hop.gendirectcall(ll_inplace_mul, v_lst, v_factor) class __extend__(pairtype(ListRepr, SliceRepr)): def rtype_getitem((r_lst, r_slic), hop): + cRESLIST = hop.inputconst(Void, hop.r_result.LIST) if r_slic == startonly_slice_repr: v_lst, v_start = hop.inputargs(r_lst, startonly_slice_repr) - return hop.gendirectcall(ll_listslice_startonly, v_lst, v_start) + return hop.gendirectcall(ll_listslice_startonly, cRESLIST, v_lst, v_start) if r_slic == startstop_slice_repr: v_lst, v_slice = hop.inputargs(r_lst, startstop_slice_repr) - return hop.gendirectcall(ll_listslice, v_lst, v_slice) + return hop.gendirectcall(ll_listslice, cRESLIST, v_lst, v_slice) if r_slic == minusone_slice_repr: v_lst, v_ignored = hop.inputargs(r_lst, minusone_slice_repr) - return hop.gendirectcall(ll_listslice_minusone, v_lst) + return hop.gendirectcall(ll_listslice_minusone, cRESLIST, v_lst) raise TyperError('getitem does not support slices with %r' % (r_slic,)) def rtype_setitem((r_lst, r_slic), hop): @@ -309,7 +316,8 @@ def rtype_add((self, _), hop): v_lst1, v_lst2 = hop.inputargs(self, self) - return hop.gendirectcall(ll_concat, v_lst1, v_lst2) + cRESLIST = hop.inputconst(Void, hop.r_result.LIST) + return hop.gendirectcall(ll_concat, cRESLIST, v_lst1, v_lst2) def rtype_inplace_add((self, _), hop): v_lst1, v_lst2 = hop.inputargs(self, self) @@ -407,12 +415,12 @@ _ll_list_resize_really(l, newsize) -def ll_copy(l): - items = l.items - length = l.length - new_lst = ll_newlist(typeOf(l), length) +def ll_copy(RESLIST, l): + items = l.ll_items() + length = l.ll_length() + new_lst = RESLIST.ll_newlist(length) i = 0 - new_items = new_lst.items + new_items = new_lst.ll_items() while i < length: new_items[i] = items[i] i += 1 @@ -423,7 +431,7 @@ def ll_list_is_true(l): # check if a list is True, allowing for None - return bool(l) and l.length != 0 + return bool(l) and l.ll_length() != 0 def ll_append(l, newitem): length = l.length @@ -511,42 +519,42 @@ return res def ll_reverse(l): - length = l.length + length = l.ll_length() i = 0 - items = l.items + items = l.ll_items() length_1_i = length-1-i while i < length_1_i: - tmp = l.items[i] + tmp = items[i] items[i] = items[length_1_i] items[length_1_i] = tmp i += 1 length_1_i -= 1 def ll_getitem_nonneg(func, l, index): - if func is dum_checkidx and (index >= l.length): + if func is dum_checkidx and (index >= l.ll_length()): raise IndexError - return l.items[index] + return l.ll_items()[index] def ll_getitem(func, l, index): - length = l.length + length = l.ll_length() if index < 0: index += length if func is dum_checkidx and (index < 0 or index >= length): raise IndexError - return l.items[index] + return l.ll_items()[index] def ll_setitem_nonneg(func, l, index, newitem): - if func is dum_checkidx and (index >= l.length): + if func is dum_checkidx and (index >= l.ll_length()): raise IndexError - l.items[index] = newitem + l.ll_items()[index] = newitem def ll_setitem(func, l, index, newitem): - length = l.length + length = l.ll_length() if index < 0: index += length if func is dum_checkidx and (index < 0 or index >= length): raise IndexError - l.items[index] = newitem + l.ll_items()[index] = newitem def ll_delitem_nonneg(func, l, index): length = l.length @@ -573,34 +581,32 @@ raise IndexError ll_delitem_nonneg(dum_nocheck, l, i) -def ll_concat(l1, l2): - len1 = l1.length - len2 = l2.length +def ll_concat(RESLIST, l1, l2): + len1 = l1.ll_length() + len2 = l2.ll_length() newlength = len1 + len2 - newitems = malloc(typeOf(l1).TO.items.TO, newlength) + l = RESLIST.ll_newlist(newlength) + newitems = l.ll_items() j = 0 - source = l1.items + source = l1.ll_items() while j < len1: newitems[j] = source[j] j += 1 i = 0 - source = l2.items + source = l2.ll_items() while i < len2: newitems[j] = source[i] i += 1 j += 1 - l = malloc(typeOf(l1).TO) - l.length = newlength - l.items = newitems return l def ll_extend(l1, l2): len1 = l1.length - len2 = l2.length + len2 = l2.ll_length() newlength = len1 + len2 _ll_list_resize_ge(l1, newlength) items = l1.items - source = l2.items + source = l2.ll_items() i = 0 j = len1 while i < len2: @@ -608,53 +614,48 @@ i += 1 j += 1 -def ll_listslice_startonly(l1, start): - len1 = l1.length +def ll_listslice_startonly(RESLIST, l1, start): + len1 = l1.ll_length() newlength = len1 - start - newitems = malloc(typeOf(l1).TO.items.TO, newlength) + l = RESLIST.ll_newlist(newlength) + newitems = l.ll_items() j = 0 - source = l1.items + source = l1.ll_items() i = start while i < len1: newitems[j] = source[i] i += 1 j += 1 - l = malloc(typeOf(l1).TO) - l.length = newlength - l.items = newitems return l -def ll_listslice(l1, slice): +def ll_listslice(RESLIST, l1, slice): start = slice.start stop = slice.stop - if stop > l1.length: - stop = l1.length + length = l1.ll_length() + if stop > length: + stop = length newlength = stop - start - newitems = malloc(typeOf(l1).TO.items.TO, newlength) + l = RESLIST.ll_newlist(newlength) + newitems = l.ll_items() j = 0 - source = l1.items + source = l1.ll_items() i = start while i < stop: newitems[j] = source[i] i += 1 j += 1 - l = malloc(typeOf(l1).TO) - l.length = newlength - l.items = newitems return l -def ll_listslice_minusone(l1): - newlength = l1.length - 1 +def ll_listslice_minusone(RESLIST, l1): + newlength = l1.ll_length() - 1 assert newlength >= 0 - newitems = malloc(typeOf(l1).TO.items.TO, newlength) + l = RESLIST.ll_newlist(newlength) + newitems = l.ll_items() j = 0 - source = l1.items + source = l1.ll_items() while j < newlength: newitems[j] = source[j] j += 1 - l = malloc(typeOf(l1).TO) - l.length = newlength - l.items = newitems return l def ll_listdelslice_startonly(l, start): @@ -690,14 +691,14 @@ _ll_list_resize_le(l, newlength) def ll_listsetslice(l1, slice, l2): - count = l2.length + count = l2.ll_length() assert count == slice.stop - slice.start, ( "setslice cannot resize lists in RPython") # XXX but it should be easy enough to support, soon start = slice.start j = start - items1 = l1.items - items2 = l2.items + items1 = l1.ll_items() + items2 = l2.ll_items() i = 0 while i < count: items1[j] = items2[i] @@ -713,13 +714,13 @@ return True if not l1 or not l2: return False - len1 = l1.length - len2 = l2.length + len1 = l1.ll_length() + len2 = l2.ll_length() if len1 != len2: return False j = 0 - items1 = l1.items - items2 = l2.items + items1 = l1.ll_items() + items2 = l2.ll_items() while j < len1: if eqfn is None: if items1[j] != items2[j]: @@ -731,8 +732,8 @@ return True def ll_listcontains(lst, obj, eqfn): - items = lst.items - lng = lst.length + items = lst.ll_items() + lng = lst.ll_length() j = 0 while j < lng: if eqfn is None: @@ -745,8 +746,8 @@ return False def ll_listindex(lst, obj, eqfn): - items = lst.items - lng = lst.length + items = lst.ll_items() + lng = lst.ll_length() j = 0 while j < lng: if eqfn is None: @@ -760,20 +761,35 @@ TEMP = GcArray(Ptr(rstr.STR)) -def ll_mul(func, l, factor): - length = l.length +def ll_inplace_mul(l, factor): + length = l.ll_length() if factor < 0: factor = 0 resultlen = length * factor - if func is dum_inplace: - res = l - _ll_list_resize(res, resultlen) - j = length - else: - res = ll_newlist(typeOf(l), resultlen) - j = 0 - source = l.items - target = res.items + res = l + _ll_list_resize(res, resultlen) + j = length + source = l.ll_items() + target = res.ll_items() + while j < resultlen: + i = 0 + while i < length: + p = j + i + target[p] = source[i] + i += 1 + j += length + return res + + +def ll_mul(RESLIST, l, factor): + length = l.ll_length() + if factor < 0: + factor = 0 + resultlen = length * factor + res = RESLIST.ll_newlist(resultlen) + j = 0 + source = l.ll_items() + target = res.ll_items() while j < resultlen: i = 0 while i < length: @@ -788,11 +804,18 @@ # # Irregular operations. -def ll_newlist(LISTPTR, length): - l = malloc(LISTPTR.TO) +def ll_newlist(LIST, length): + l = malloc(LIST) l.length = length - l.items = malloc(LISTPTR.TO.items.TO, length) + l.items = malloc(LIST.items.TO, length) return l +ll_newlist = typeMethod(ll_newlist) + +def ll_length(l): + return l.length + +def ll_items(l): + return l.items def rtype_newlist(hop): nb_args = hop.nb_args @@ -807,9 +830,9 @@ hop.genop('simple_call', [v_meth, v_item], resulttype = robject.pyobj_repr) return v_result r_listitem = r_list.item_repr - c1 = hop.inputconst(Void, r_list.lowleveltype) - c2 = hop.inputconst(Signed, nb_args) - v_result = hop.gendirectcall(ll_newlist, c1, c2) + LIST = r_list.LIST + cno = hop.inputconst(Signed, nb_args) + v_result = hop.gendirectcall(LIST.ll_newlist, cno) v_func = hop.inputconst(Void, dum_nocheck) for i in range(nb_args): ci = hop.inputconst(Signed, i) @@ -817,24 +840,23 @@ hop.gendirectcall(ll_setitem_nonneg, v_func, v_result, ci, v_item) return v_result -def ll_alloc_and_set(LISTPTR, count, item): +def ll_alloc_and_set(LIST, count, item): if count < 0: count = 0 - l = malloc(LISTPTR.TO) - l.length = count - l.items = malloc(LISTPTR.TO.items.TO, count) + l = LIST.ll_newlist(count) if item: # as long as malloc it is known to zero the allocated memory avoid zeroing twice i = 0 + items = l.ll_items() while i < count: - l.items[i] = item + items[i] = item i += 1 return l def rtype_alloc_and_set(hop): r_list = hop.r_result v_count, v_item = hop.inputargs(Signed, r_list.item_repr) - c1 = hop.inputconst(Void, r_list.lowleveltype) - return hop.gendirectcall(ll_alloc_and_set, c1, v_count, v_item) + cLIST = hop.inputconst(Void, r_list.LIST) + return hop.gendirectcall(ll_alloc_and_set, cLIST, v_count, v_item) # ____________________________________________________________ # @@ -869,13 +891,18 @@ def ll_listnext(iter): l = iter.list index = iter.index - if index >= l.length: + if index >= l.ll_length(): raise StopIteration iter.index = index + 1 - return l.items[index] + return l.ll_items()[index] # ___________________________________________________________ LIST_OF_STR = GcStruct("list", ("length", Signed), - ("items", Ptr(GcArray(Ptr(rstr.STR))))) + ("items", Ptr(GcArray(Ptr(rstr.STR)))), + adtmeths = { + "ll_newlist": ll_newlist, + "ll_length": ll_length, + "ll_items": ll_items, + }) Modified: pypy/dist/pypy/rpython/rrange.py ============================================================================== --- pypy/dist/pypy/rpython/rrange.py (original) +++ pypy/dist/pypy/rpython/rrange.py Sun Oct 23 22:08:36 2005 @@ -141,18 +141,18 @@ else: # cannot build a RANGE object, needs a real list r_list = hop.r_result - c1 = hop.inputconst(Void, r_list.lowleveltype) - return hop.gendirectcall(ll_range2list, c1, vstart, vstop, vstep) + cLIST = hop.inputconst(Void, r_list.lowleveltype.TO) + return hop.gendirectcall(ll_range2list, cLIST, vstart, vstop, vstep) rtype_builtin_xrange = rtype_builtin_range -def ll_range2list(LISTPTR, start, stop, step): +def ll_range2list(LIST, start, stop, step): if step == 0: raise ValueError length = _ll_rangelen(start, stop, step) - l = ll_newlist(LISTPTR, length) + l = LIST.ll_newlist(length) idx = 0 - items = l.items + items = l.ll_items() while idx < length: items[idx] = start start += step Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Sun Oct 23 22:08:36 2005 @@ -156,12 +156,10 @@ if not isinstance(r_lst, ListRepr): raise TyperError("string.join of non-list: %r" % r_lst) v_str, v_lst = hop.inputargs(string_repr, r_lst) - cname = inputconst(Void, "length") - v_length = hop.genop("getfield", [v_lst, cname], - resulttype=Signed) - cname = inputconst(Void, "items") - v_items = hop.genop("getfield", [v_lst, cname], - resulttype=r_lst.lowleveltype.TO.items) + LIST = r_lst.lowleveltype.TO + v_length = hop.gendirectcall(LIST.ll_length, v_lst) + v_items = hop.gendirectcall(LIST.ll_items, v_lst) + if hop.args_s[0].is_constant() and hop.args_s[0].const == '': if r_lst.item_repr == string_repr: llfn = ll_join_strs @@ -179,9 +177,9 @@ def rtype_method_split(_, hop): v_str, v_chr = hop.inputargs(string_repr, char_repr) - c = hop.inputconst(Void, hop.r_result.lowleveltype) + cLIST = hop.inputconst(Void, hop.r_result.lowleveltype.TO) hop.exception_cannot_occur() - return hop.gendirectcall(ll_split_chr, c, v_str, v_chr) + return hop.gendirectcall(ll_split_chr, cLIST, v_str, v_chr) def rtype_method_replace(_, hop): if not (hop.args_r[1] == char_repr and hop.args_r[2] == char_repr): @@ -958,8 +956,7 @@ j += 1 return newstr -def ll_split_chr(LISTPTR, s, c): - from pypy.rpython.rlist import ll_newlist +def ll_split_chr(LIST, s, c): chars = s.chars strlen = len(chars) count = 1 @@ -968,9 +965,8 @@ if chars[i] == c: count += 1 i += 1 - res = ll_newlist(LISTPTR, count) - items = res.items - + res = LIST.ll_newlist(count) + items = res.ll_items() i = 0 j = 0 resindex = 0 Modified: pypy/dist/pypy/rpython/rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/rtuple.py (original) +++ pypy/dist/pypy/rpython/rtuple.py Sun Oct 23 22:08:36 2005 @@ -62,9 +62,9 @@ from pypy.rpython import rlist nitems = len(self.items_r) vtup = hop.inputarg(self, 0) - c1 = inputconst(Void, hop.r_result.lowleveltype) - c2 = inputconst(Signed, nitems) - vlist = hop.gendirectcall(rlist.ll_newlist, c1, c2) + LIST = hop.r_result.lowleveltype.TO + cno = inputconst(Signed, nitems) + vlist = hop.gendirectcall(LIST.ll_newlist, cno) v_func = hop.inputconst(Void, rlist.dum_nocheck) for index in range(nitems): name = self.fieldnames[index] 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 Sun Oct 23 22:08:36 2005 @@ -452,4 +452,21 @@ assert len(a) == 10 assert a.h_length() == 10 + +def test_adt_typemethod(): + def h_newstruct(S): + return malloc(S) + h_newstruct = typeMethod(h_newstruct) + S = GcStruct('s', ('x', Signed), + adtmeths={"h_newstruct": h_newstruct}) + + s = S.h_newstruct() + + assert typeOf(s) == Ptr(S) + + Sprime = GcStruct('s', ('x', Signed), + adtmeths={"h_newstruct": h_newstruct}) + + assert S == Sprime + 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 Sun Oct 23 22:08:36 2005 @@ -21,7 +21,7 @@ def sample_list(): # [42, 43, 44, 45] rlist = ListRepr(None, signed_repr) rlist.setup() - l = ll_newlist(rlist.lowleveltype, 3) + l = ll_newlist(rlist.lowleveltype.TO, 3) ll_setitem(l, 0, 42) ll_setitem(l, -2, 43) ll_setitem_nonneg(l, 2, 44) @@ -61,21 +61,22 @@ l = sample_list() ll_extend(l, l) check_list(l, [42, 43, 44, 45] * 2) - l1 = ll_concat(l, l) + l1 = ll_concat(typeOf(l).TO, l, l) assert l1 != l check_list(l1, [42, 43, 44, 45] * 4) def test_rlist_slice(): l = sample_list() - check_list(ll_listslice_startonly(l, 0), [42, 43, 44, 45]) - check_list(ll_listslice_startonly(l, 1), [43, 44, 45]) - check_list(ll_listslice_startonly(l, 2), [44, 45]) - check_list(ll_listslice_startonly(l, 3), [45]) - check_list(ll_listslice_startonly(l, 4), []) + LIST = typeOf(l).TO + check_list(ll_listslice_startonly(LIST, l, 0), [42, 43, 44, 45]) + check_list(ll_listslice_startonly(LIST, l, 1), [43, 44, 45]) + check_list(ll_listslice_startonly(LIST, l, 2), [44, 45]) + check_list(ll_listslice_startonly(LIST, l, 3), [45]) + check_list(ll_listslice_startonly(LIST, l, 4), []) for start in range(5): for stop in range(start, 8): s = ll_newslice(start, stop) - check_list(ll_listslice(l, s), [42, 43, 44, 45][start:stop]) + check_list(ll_listslice(LIST, l, s), [42, 43, 44, 45][start:stop]) def test_rlist_delslice(): l = sample_list() @@ -104,7 +105,7 @@ ll_setitem(l2, i, n) n += 1 s = ll_newslice(start, stop) - l2 = ll_listslice(l2, s) + l2 = ll_listslice(typeOf(l2).TO, l2, s) ll_listsetslice(l1, s, l2) check_list(l1, expected) Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Sun Oct 23 22:08:36 2005 @@ -101,7 +101,7 @@ p = lltype.Ptr(rlist.LIST_OF_STR) def _RPyListOfString_New(length=lltype.Signed): - return rlist.ll_newlist(p, length) + return rlist.LIST_OF_STR.ll_newlist(length) def _RPyListOfString_SetItem(l=p, index=lltype.Signed, From tismer at codespeak.net Sun Oct 23 22:50:33 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 23 Oct 2005 22:50:33 +0200 (CEST) Subject: [pypy-svn] r18849 - pypy/dist/pypy/translator/c/src Message-ID: <20051023205033.D367727B82@code1.codespeak.net> Author: tismer Date: Sun Oct 23 22:50:32 2005 New Revision: 18849 Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: check for empty initial result 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 Sun Oct 23 22:50:32 2005 @@ -342,6 +342,8 @@ { if (!d->first_done) { d->first_done = 1; + if (d->d_name == NULL) + return NULL; return d; } if (!FindNextFile(d->hFind, &d->FileData)) From tismer at codespeak.net Sun Oct 23 22:51:11 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 23 Oct 2005 22:51:11 +0200 (CEST) Subject: [pypy-svn] r18850 - pypy/dist/pypy/translator/locality Message-ID: <20051023205111.2EE7827B86@code1.codespeak.net> Author: tismer Date: Sun Oct 23 22:51:10 2005 New Revision: 18850 Modified: pypy/dist/pypy/translator/locality/projection.py Log: the cheap case of computing a norm2 on a one-dimensional vector... Modified: pypy/dist/pypy/translator/locality/projection.py ============================================================================== --- pypy/dist/pypy/translator/locality/projection.py (original) +++ pypy/dist/pypy/translator/locality/projection.py Sun Oct 23 22:51:10 2005 @@ -87,6 +87,8 @@ return Vector([-k for k in self.coords]) def norm2(self): + if len(self.coords) == 1: + return abs(self.coords[0]) return sqrt(sum([k * k for k in self.coords])) def getdim(self): @@ -138,7 +140,7 @@ def forcevector(self): # weighted implementation of the "rubber2" algorithm, # from "PolyTop", (C) Christian Tismer / Gerhard G. Thomas 1992 - vec = self.position * 0.0 + vec = Vector() for w, rel in zip(self.weights, self.relations): tmp = rel.position - self.position lng = tmp.norm2() From tismer at codespeak.net Sun Oct 23 23:22:48 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Sun, 23 Oct 2005 23:22:48 +0200 (CEST) Subject: [pypy-svn] r18851 - pypy/dist/pypy/translator/c/src Message-ID: <20051023212248.E6E2627B55@code1.codespeak.net> Author: tismer Date: Sun Oct 23 23:22:47 2005 New Revision: 18851 Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: just formatting 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 Sun Oct 23 23:22:47 2005 @@ -346,8 +346,7 @@ return NULL; return d; } - if (!FindNextFile(d->hFind, &d->FileData)) - { + if (!FindNextFile(d->hFind, &d->FileData)) { errno = GetLastError(); if (errno == ERROR_NO_MORE_FILES) errno = 0; From pedronis at codespeak.net Mon Oct 24 02:32:50 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 24 Oct 2005 02:32:50 +0200 (CEST) Subject: [pypy-svn] r18852 - pypy/dist/pypy/rpython Message-ID: <20051024003250.0B94527B6A@code1.codespeak.net> Author: pedronis Date: Mon Oct 24 02:32:49 2005 New Revision: 18852 Modified: pypy/dist/pypy/rpython/annlowlevel.py Log: bug Modified: pypy/dist/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/dist/pypy/rpython/annlowlevel.py (original) +++ pypy/dist/pypy/rpython/annlowlevel.py Mon Oct 24 02:32:49 2005 @@ -36,7 +36,7 @@ if s is None: compact = getattr(val, 'compact_repr', None) if compact is None: - s = repr(s) + s = repr(val) else: s = compact() return s + 'Const' From tismer at codespeak.net Mon Oct 24 02:44:13 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 24 Oct 2005 02:44:13 +0200 (CEST) Subject: [pypy-svn] r18853 - pypy/dist/pypy/translator/c/src Message-ID: <20051024004413.42E1E27B6A@code1.codespeak.net> Author: tismer Date: Mon Oct 24 02:44:12 2005 New Revision: 18853 Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: reworked things to be a little shorter, moved the string argument into the dir structure, removed the first_done field, and made the code a bit shorter (and partially maybe a bit less readable?), after Armin said this can be kept this way. 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 Oct 24 02:44:12 2005 @@ -305,55 +305,45 @@ HANDLE hFind; WIN32_FIND_DATA FileData; char *d_name; /* faking dirent */ - int first_done; + char arg[1]; /*also used as flag */ } DIR; static DIR *opendir(char *dirname) { - DIR *d = malloc(sizeof(DIR)); int lng = strlen(dirname); - char *mangled = strcpy(_alloca(lng + 5), dirname); - char *p = mangled + lng; + DIR *d = malloc(sizeof(DIR) + lng + 4); - if (d == NULL) - return NULL; - - if (lng && p[-1] == '\\') - p--; - strcpy(p, "\\*.*"); - - d->first_done = 0; - d->hFind = FindFirstFile(mangled, &d->FileData); - if (d->hFind == INVALID_HANDLE_VALUE) { - d->d_name = NULL; - errno = GetLastError(); - if (errno == ERROR_FILE_NOT_FOUND) { - errno = 0; - return d; + if (d != NULL) { + strcpy(&d->arg, dirname); + strcpy(&d->arg + lng, "\\*.*" + (&d->arg + lng - 1 == '\\')); + d->hFind = FindFirstFile(&d->arg, &d->FileData); + d->d_name = d->FileData.cFileName; + if (d->hFind == INVALID_HANDLE_VALUE) { + d->d_name = NULL; + if (GetLastError() != ERROR_FILE_NOT_FOUND) { + errno = GetLastError(); + free(d); + d = NULL; + } } - free(d); - return NULL; } - d->d_name = d->FileData.cFileName; return d; } static struct dirent *readdir(DIR *d) { - if (!d->first_done) { - d->first_done = 1; - if (d->d_name == NULL) - return NULL; - return d; - } - if (!FindNextFile(d->hFind, &d->FileData)) { - errno = GetLastError(); - if (errno == ERROR_NO_MORE_FILES) - errno = 0; - return NULL; + if (d->arg[0]) + d->arg[0] = 0; /* use existing result first time */ + else { + if (FindNextFile(d->hFind, &d->FileData)) + d->d_name = d->FileData.cFileName; + else { + d->d_name = NULL; + if (GetLastError() != ERROR_NO_MORE_FILES) + errno = GetLastError(); + } } - d->d_name = d->FileData.cFileName; - return d; + return d->d_name ? d : NULL; } static int closedir(DIR *d) From tismer at codespeak.net Mon Oct 24 02:48:58 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 24 Oct 2005 02:48:58 +0200 (CEST) Subject: [pypy-svn] r18854 - pypy/dist/pypy/translator/c/src Message-ID: <20051024004858.216A827B6A@code1.codespeak.net> Author: tismer Date: Mon Oct 24 02:48:57 2005 New Revision: 18854 Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: just tabs 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 Oct 24 02:48:57 2005 @@ -322,7 +322,7 @@ d->d_name = NULL; if (GetLastError() != ERROR_FILE_NOT_FOUND) { errno = GetLastError(); - free(d); + free(d); d = NULL; } } From pedronis at codespeak.net Mon Oct 24 03:00:45 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 24 Oct 2005 03:00:45 +0200 (CEST) Subject: [pypy-svn] r18855 - in pypy/dist/pypy/rpython: . test Message-ID: <20051024010045.848C927B73@code1.codespeak.net> Author: pedronis Date: Mon Oct 24 03:00:43 2005 New Revision: 18855 Modified: pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rmodel.py pypy/dist/pypy/rpython/rtyper.py pypy/dist/pypy/rpython/test/test_rdict.py Log: coalesce for instances in rdict, this toghether with the same for rlist has killed around 100 functions in the translated result (after inlining). Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Mon Oct 24 03:00:43 2005 @@ -51,7 +51,8 @@ rtyper.getrepr(dictkey.s_rdict_hashfn)) else: custom_eq_hash = None - return DictRepr(lambda: rtyper.getrepr(s_key), + return DictRepr(rtyper, + lambda: rtyper.getrepr(s_key), lambda: rtyper.getrepr(s_value), dictkey, dictvalue, @@ -60,37 +61,84 @@ def rtyper_makekey(self): return (self.__class__, self.dictdef.dictkey, self.dictdef.dictvalue) +class DictTrait: + # avoid explosion of one helper function per repr + # vs. layout and functions + + def __init__(self, dictrepr): + self.DICT = dictrepr.DICT + self.DICTENTRYARRAY = dictrepr.DICTENTRYARRAY + self.custom_eq_hash = False + self.ll_keyhash = dictrepr.ll_keyhash + self.ll_keyeq = dictrepr.ll_keyeq + + def _freeze_(self): + return True + + def __repr__(self): + return "DictT %s" % self.DICT._short_name() + +def dict_trait(rtyper, dictrepr): + if dictrepr.custom_eq_hash: # in this case use there is not much point in not just using the repr + return dictrepr + + key = (dictrepr.DICT, dictrepr.ll_keyhash, dictrepr.ll_keyeq) + try: + return rtyper._dict_traits[key] + except KeyError: + trait = DictTrait(dictrepr) + rtyper._dict_traits[key] = trait + return trait + + class DictRepr(rmodel.Repr): - def __init__(self, key_repr, value_repr, dictkey=None, dictvalue=None, + def __init__(self, rtyper, key_repr, value_repr, dictkey=None, dictvalue=None, custom_eq_hash=None): + self.rtyper = rtyper self.DICT = lltype.GcForwardReference() self.lowleveltype = lltype.Ptr(self.DICT) + self.custom_eq_hash = custom_eq_hash is not None if not isinstance(key_repr, rmodel.Repr): # not computed yet, done by setup() assert callable(key_repr) self._key_repr_computer = key_repr else: - self.key_repr = key_repr + self.external_key_repr, self.key_repr = self.pickkeyrepr(key_repr) if not isinstance(value_repr, rmodel.Repr): # not computed yet, done by setup() assert callable(value_repr) self._value_repr_computer = value_repr else: - self.value_repr = value_repr + self.external_value_repr, self.value_repr = self.pickrepr(value_repr) self.dictkey = dictkey self.dictvalue = dictvalue self.dict_cache = {} - self.custom_eq_hash = custom_eq_hash is not None self._custom_eq_hash_repr = custom_eq_hash + self._trait = None # cache for get_trait # setup() needs to be called to finish this initialization + + def pickrepr(self, item_repr): + if self.custom_eq_hash: + return item_repr, item_repr + else: + return rmodel.externalvsinternal(self.rtyper, item_repr) + def pickkeyrepr(self, key_repr): + external, internal = self.pickrepr(key_repr) + if external != internal: + internal = external + while not self.rtyper.needs_hash_support(internal.classdef.cls): + internal = internal.rbase + return external, internal + def compact_repr(self): return 'DictR %s %s' % (self.key_repr.compact_repr(), self.value_repr.compact_repr()) def _setup_repr(self): if 'key_repr' not in self.__dict__: - self.key_repr = self._key_repr_computer() + key_repr = self._key_repr_computer() + self.external_key_repr, self.key_repr = self.pickkeyrepr(key_repr) if 'value_repr' not in self.__dict__: - self.value_repr = self._value_repr_computer() + self.external_value_repr, self.value_repr = self.pickrepr(self._value_repr_computer()) if isinstance(self.DICT, lltype.GcForwardReference): self.DICTKEY = self.key_repr.lowleveltype self.DICTVALUE = self.value_repr.lowleveltype @@ -114,6 +162,17 @@ self.ll_keyeq = self.key_repr.get_ll_eq_function() # can be None self.ll_keyhash = self.key_repr.get_ll_hash_function() + def recast_value(self, llops, v): + return llops.convertvar(v, self.value_repr, self.external_value_repr) + + def recast_key(self, llops, v): + return llops.convertvar(v, self.key_repr, self.external_key_repr) + + def get_trait(self): + if self._trait is None: + self._trait = dict_trait(self.rtyper, self) + return self._trait + def convert_const(self, dictobj): # get object from bound dict methods #dictobj = getattr(dictobj, '__self__', dictobj) @@ -185,21 +244,22 @@ def rtype_method_get(self, hop): v_dict, v_key, v_default = hop.inputargs(self, self.key_repr, self.value_repr) - crepr = hop.inputconst(lltype.Void, self) + ctrait = hop.inputconst(lltype.Void, self.get_trait()) hop.exception_cannot_occur() - return hop.gendirectcall(ll_get, v_dict, v_key, v_default, crepr) + v_res = hop.gendirectcall(ll_get, v_dict, v_key, v_default, ctrait) + return self.recast_value(hop.llops, v_res) def rtype_method_copy(self, hop): v_dict, = hop.inputargs(self) - crepr = hop.inputconst(lltype.Void, self) + ctrait = hop.inputconst(lltype.Void, self.get_trait()) hop.exception_cannot_occur() - return hop.gendirectcall(ll_copy, v_dict, crepr) + return hop.gendirectcall(ll_copy, v_dict, ctrait) def rtype_method_update(self, hop): v_dic1, v_dic2 = hop.inputargs(self, self) - crepr = hop.inputconst(lltype.Void, self) + ctrait = hop.inputconst(lltype.Void, self.get_trait()) hop.exception_cannot_occur() - return hop.gendirectcall(ll_update, v_dic1, v_dic2, crepr) + return hop.gendirectcall(ll_update, v_dic1, v_dic2, ctrait) def _rtype_method_kvi(self, hop, spec): v_dic, = hop.inputargs(self) @@ -239,27 +299,28 @@ def rtype_getitem((r_dict, r_key), hop): v_dict, v_key = hop.inputargs(r_dict, r_dict.key_repr) - crepr = hop.inputconst(lltype.Void, r_dict) + ctrait = hop.inputconst(lltype.Void, r_dict.get_trait()) hop.has_implicit_exception(KeyError) # record that we know about it hop.exception_is_here() - return hop.gendirectcall(ll_dict_getitem, v_dict, v_key, crepr) + v_res = hop.gendirectcall(ll_dict_getitem, v_dict, v_key, ctrait) + return r_dict.recast_value(hop.llops, v_res) def rtype_delitem((r_dict, r_key), hop): v_dict, v_key = hop.inputargs(r_dict, r_dict.key_repr) - crepr = hop.inputconst(lltype.Void, r_dict) + ctrait = hop.inputconst(lltype.Void, r_dict.get_trait()) hop.has_implicit_exception(KeyError) # record that we know about it hop.exception_is_here() - return hop.gendirectcall(ll_dict_delitem, v_dict, v_key, crepr) + return hop.gendirectcall(ll_dict_delitem, v_dict, v_key, ctrait) def rtype_setitem((r_dict, r_key), hop): v_dict, v_key, v_value = hop.inputargs(r_dict, r_dict.key_repr, r_dict.value_repr) - crepr = hop.inputconst(lltype.Void, r_dict) - hop.gendirectcall(ll_dict_setitem, v_dict, v_key, v_value, crepr) + ctrait = hop.inputconst(lltype.Void, r_dict.get_trait()) + hop.gendirectcall(ll_dict_setitem, v_dict, v_key, v_value, ctrait) def rtype_contains((r_dict, r_key), hop): v_dict, v_key = hop.inputargs(r_dict, r_dict.key_repr) - crepr = hop.inputconst(lltype.Void, r_dict) - return hop.gendirectcall(ll_contains, v_dict, v_key, crepr) + ctrait = hop.inputconst(lltype.Void, r_dict.get_trait()) + return hop.gendirectcall(ll_contains, v_dict, v_key, ctrait) class __extend__(pairtype(DictRepr, DictRepr)): def convert_from_to((r_dict1, r_dict2), v, llops): @@ -295,22 +356,22 @@ # check if a dict is True, allowing for None return bool(d) and d.num_items != 0 -def ll_dict_getitem(d, key, dictrepr): - entry = ll_dict_lookup(d, key, dictrepr) +def ll_dict_getitem(d, key, dictrait): + entry = ll_dict_lookup(d, key, dictrait) if entry.valid: return entry.value else: raise KeyError -def ll_dict_setitem(d, key, value, dictrepr): - entry = ll_dict_lookup(d, key, dictrepr) +def ll_dict_setitem(d, key, value, dictrait): + entry = ll_dict_lookup(d, key, dictrait) entry.value = value if entry.valid: return - if dictrepr.custom_eq_hash: - hash = hlinvoke(dictrepr.r_rdict_hashfn, d.fnkeyhash, key) + if dictrait.custom_eq_hash: + hash = hlinvoke(dictrait.r_rdict_hashfn, d.fnkeyhash, key) else: - hash = dictrepr.ll_keyhash(key) + hash = dictrait.ll_keyhash(key) entry.key = key entry.hash = hash entry.valid = True @@ -319,10 +380,10 @@ entry.everused = True d.num_pristine_entries -= 1 if d.num_pristine_entries <= len(d.entries) / 3: - ll_dict_resize(d, dictrepr) + ll_dict_resize(d, dictrait) -def ll_dict_delitem(d, key, dictrepr): - entry = ll_dict_lookup(d, key, dictrepr) +def ll_dict_delitem(d, key, dictrait): + entry = ll_dict_lookup(d, key, dictrait) if not entry.valid: raise KeyError entry.valid = False @@ -337,9 +398,9 @@ entry.value = lltype.nullptr(valuetype.TO) num_entries = len(d.entries) if num_entries > DICT_INITSIZE and d.num_items < num_entries / 4: - ll_dict_resize(d, dictrepr) + ll_dict_resize(d, dictrait) -def ll_dict_resize(d, dictrepr): +def ll_dict_resize(d, dictrait): old_entries = d.entries old_size = len(old_entries) # make a 'new_size' estimate and shrink it if there are many @@ -353,7 +414,7 @@ while i < old_size: entry = old_entries[i] if entry.valid: - new_entry = ll_dict_lookup(d, entry.key, dictrepr) + new_entry = ll_dict_lookup(d, entry.key, dictrait) new_entry.key = entry.key new_entry.hash = entry.hash new_entry.value = entry.value @@ -364,11 +425,11 @@ # ------- a port of CPython's dictobject.c's lookdict implementation ------- PERTURB_SHIFT = 5 -def ll_dict_lookup(d, key, dictrepr): - if dictrepr.custom_eq_hash: - hash = hlinvoke(dictrepr.r_rdict_hashfn, d.fnkeyhash, key) +def ll_dict_lookup(d, key, dictrait): + if dictrait.custom_eq_hash: + hash = hlinvoke(dictrait.r_rdict_hashfn, d.fnkeyhash, key) else: - hash = dictrepr.ll_keyhash(key) + hash = dictrait.ll_keyhash(key) entries = d.entries mask = len(entries) - 1 i = r_uint(hash & mask) @@ -379,14 +440,14 @@ if checkingkey == key: return entry # found the entry if entry.hash == hash: - if dictrepr.custom_eq_hash: - res = hlinvoke(dictrepr.r_rdict_eqfn, d.fnkeyeq, checkingkey, key) + if dictrait.custom_eq_hash: + res = hlinvoke(dictrait.r_rdict_eqfn, d.fnkeyeq, checkingkey, key) if (entries != d.entries or not entry.valid or entry.key != checkingkey): # the compare did major nasty stuff to the dict: start over - return ll_dict_lookup(d, key, dictrepr) + return ll_dict_lookup(d, key, dictrait) else: - res = dictrepr.ll_keyeq is not None and dictrepr.ll_keyeq(checkingkey, key) + res = dictrait.ll_keyeq is not None and dictrait.ll_keyeq(checkingkey, key) if res: return entry # found the entry freeslot = lltype.nullptr(lltype.typeOf(entry).TO) @@ -408,14 +469,14 @@ if checkingkey == key: return entry if entry.hash == hash: - if dictrepr.custom_eq_hash: - res = hlinvoke(dictrepr.r_rdict_eqfn, d.fnkeyeq, checkingkey, key) + if dictrait.custom_eq_hash: + res = hlinvoke(dictrait.r_rdict_eqfn, d.fnkeyeq, checkingkey, key) if (entries != d.entries or not entry.valid or entry.key != checkingkey): # the compare did major nasty stuff to the dict: start over - return ll_dict_lookup(d, key, dictrepr) + return ll_dict_lookup(d, key, dictrait) else: - res = dictrepr.ll_keyeq is not None and dictrepr.ll_keyeq(checkingkey, key) + res = dictrait.ll_keyeq is not None and dictrait.ll_keyeq(checkingkey, key) if res: return entry elif not freeslot: @@ -428,15 +489,15 @@ DICT_INITSIZE = 8 -def ll_newdict(dictrepr): - d = lltype.malloc(dictrepr.DICT) - d.entries = lltype.malloc(dictrepr.DICTENTRYARRAY, DICT_INITSIZE) +def ll_newdict(dictrait): + d = lltype.malloc(dictrait.DICT) + d.entries = lltype.malloc(dictrait.DICTENTRYARRAY, DICT_INITSIZE) d.num_items = 0 # but still be explicit d.num_pristine_entries = DICT_INITSIZE return d -def ll_copy_extra_data(targetdict, sourcedict, dictrepr): - if dictrepr.custom_eq_hash: +def ll_copy_extra_data(targetdict, sourcedict, dictrait): + if dictrait.custom_eq_hash: targetdict.fnkeyeq = sourcedict.fnkeyeq targetdict.fnkeyhash = sourcedict.fnkeyhash @@ -446,8 +507,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) - crepr = hop.inputconst(lltype.Void, r_dict) - v_result = hop.gendirectcall(ll_newdict, crepr) + ctrait = hop.inputconst(lltype.Void, r_dict.get_trait()) + v_result = hop.gendirectcall(ll_newdict, ctrait) return v_result def rtype_r_dict(hop): @@ -456,9 +517,9 @@ raise TyperError("r_dict() call does not return an r_dict instance") v_eqfn, v_hashfn = hop.inputargs(r_dict.r_rdict_eqfn, r_dict.r_rdict_hashfn) - crepr = hop.inputconst(lltype.Void, r_dict) + ctrait = hop.inputconst(lltype.Void, r_dict) hop.exception_cannot_occur() - v_result = hop.gendirectcall(ll_newdict, crepr) + v_result = hop.gendirectcall(ll_newdict, ctrait) if r_dict.r_rdict_eqfn.lowleveltype != lltype.Void: cname = hop.inputconst(lltype.Void, 'fnkeyeq') hop.genop('setfield', [v_result, cname, v_eqfn]) @@ -486,13 +547,22 @@ return hop.gendirectcall(ll_dictiter, citerptr, v_dict) def rtype_next(self, hop): + variant = self.variant v_iter, = hop.inputargs(self) - r_list = hop.r_result v_func = hop.inputconst(lltype.Void, dum_variant[self.variant]) - c1 = hop.inputconst(lltype.Void, r_list.lowleveltype) + if variant in ('keys', 'values'): + c1 = hop.inputconst(lltype.Void, None) + else: + c1 = hop.inputconst(lltype.Void, hop.r_result.lowleveltype) hop.has_implicit_exception(StopIteration) # record that we know about it hop.exception_is_here() - return hop.gendirectcall(ll_dictnext, v_iter, v_func, c1) + v = hop.gendirectcall(ll_dictnext, v_iter, v_func, c1) + if variant == 'keys': + return self.r_dict.recast_key(hop.llops, v) + elif variant == 'values': + return self.r_dict.recast_value(hop.llops, v) + else: + return v def ll_dictiter(ITERPTR, d): iter = lltype.malloc(ITERPTR.TO) @@ -513,8 +583,8 @@ iter.index = index if func is dum_items: r = lltype.malloc(RETURNTYPE.TO) - r.item0 = entry.key - r.item1 = entry.value + r.item0 = recast(RETURNTYPE.TO.item0, entry.key) + r.item1 = recast(RETURNTYPE.TO.item1, entry.value) return r elif func is dum_keys: return entry.key @@ -527,20 +597,20 @@ # _____________________________________________________________ # methods -def ll_get(dict, key, default, dictrepr): - entry = ll_dict_lookup(dict, key, dictrepr) +def ll_get(dict, key, default, dictrait): + entry = ll_dict_lookup(dict, key, dictrait) if entry.valid: return entry.value else: return default -def ll_copy(dict, dictrepr): +def ll_copy(dict, dictrait): dictsize = len(dict.entries) - d = lltype.malloc(dictrepr.DICT) - d.entries = lltype.malloc(dictrepr.DICTENTRYARRAY, dictsize) + d = lltype.malloc(dictrait.DICT) + d.entries = lltype.malloc(dictrait.DICTENTRYARRAY, dictsize) d.num_items = dict.num_items d.num_pristine_entries = dict.num_pristine_entries - ll_copy_extra_data(d, dict, dictrepr) + ll_copy_extra_data(d, dict, dictrait) i = 0 while i < dictsize: d_entry = d.entries[i] @@ -561,7 +631,7 @@ d.num_items = 0 d.num_pristine_entries = DICT_INITSIZE -def ll_update(dic1, dic2, dictrepr): +def ll_update(dic1, dic2, dictrait): # XXX warning, no protection against ll_dict_setitem mutating dic2 d2len = len(dic2.entries) entries = dic2.entries @@ -569,7 +639,7 @@ while i < d2len: entry = entries[i] if entry.valid: - ll_dict_setitem(dic1, entry.key, entry.value, dictrepr) + ll_dict_setitem(dic1, entry.key, entry.value, dictrait) i += 1 # this is an implementation of keys(), values() and items() @@ -577,6 +647,12 @@ # note that by specialization on func, three different # and very efficient functions are created. +def recast(P, v): + if isinstance(P, lltype.Ptr): + return lltype.cast_pointer(P, v) + else: + return v + def ll_kvi(dic, LIST, func): res = LIST.ll_newlist(dic.num_items) dlen = len(dic.entries) @@ -587,25 +663,20 @@ while i < dlen: entry = entries[i] if entry.valid: + ELEM = lltype.typeOf(items).TO.OF if func is dum_items: - r = lltype.malloc(LIST.items.TO.OF.TO) - r.item0 = entry.key - r.item1 = entry.value + r = lltype.malloc(ELEM.TO) + r.item0 = recast(ELEM.TO.item0, entry.key) + r.item1 = recast(ELEM.TO.item1, entry.value) items[p] = r elif func is dum_keys: - k = entry.key - if isinstance(LIST.items.TO.OF, lltype.Ptr): - k = lltype.cast_pointer(LIST.items.TO.OF, k) - items[p] = k + items[p] = recast(ELEM, entry.key) elif func is dum_values: - val = entry.value - if isinstance(LIST.items.TO.OF, lltype.Ptr): - val = lltype.cast_pointer(LIST.items.TO.OF, val) - items[p] = val + items[p] = recast(ELEM, entry.value) p += 1 i += 1 return res -def ll_contains(d, key, dictrepr): - entry = ll_dict_lookup(d, key, dictrepr) +def ll_contains(d, key, dictrait): + entry = ll_dict_lookup(d, key, dictrait) return entry.valid Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Mon Oct 24 03:00:43 2005 @@ -2,7 +2,7 @@ from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst -from pypy.rpython.rmodel import IteratorRepr +from pypy.rpython.rmodel import IteratorRepr, externalvsinternal from pypy.rpython.rslice import SliceRepr from pypy.rpython.rslice import startstop_slice_repr, startonly_slice_repr from pypy.rpython.rslice import minusone_slice_repr @@ -54,25 +54,17 @@ assert callable(item_repr) self._item_repr_computer = item_repr else: - self.set_item_repr(item_repr) + self.external_item_repr, self.item_repr = externalvsinternal(rtyper, item_repr) self.listitem = listitem self.list_cache = {} # setup() needs to be called to finish this initialization - - def set_item_repr(self, item_repr): - from pypy.rpython import rclass - if isinstance(item_repr, rclass.AbstractInstanceRepr): - self.item_repr = rclass.getinstancerepr(self.rtyper, None) - self.external_item_repr = item_repr - else: - self.item_repr = self.external_item_repr = item_repr def recast(self, llops, v): return llops.convertvar(v, self.item_repr, self.external_item_repr) def _setup_repr(self): if 'item_repr' not in self.__dict__: - self.set_item_repr(self._item_repr_computer()) + self.external_item_repr, self.item_repr = externalvsinternal(self.rtyper, self._item_repr_computer()) if isinstance(self.LIST, GcForwardReference): ITEM = self.item_repr.lowleveltype ITEMARRAY = GcArray(ITEM) Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Mon Oct 24 03:00:43 2005 @@ -319,6 +319,14 @@ else: return getattr(classdef.cls, '_alloc_flavor_', 'gc').startswith('gc') +def externalvsinternal(rtyper, item_repr): # -> external_item_repr, (internal_)item_repr + from pypy.rpython import rclass + if isinstance(item_repr, rclass.AbstractInstanceRepr): + return item_repr, rclass.getinstancerepr(rtyper, None) + else: + return item_repr, item_repr + + # logging/warning import py Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Mon Oct 24 03:00:43 2005 @@ -62,6 +62,7 @@ self._reprs_must_call_setup = [] self._seen_reprs_must_call_setup = {} self.specialized_ll_functions = {} + self._dict_traits = {} self.class_reprs = {} self.instance_reprs = {} self.pbc_reprs = {} Modified: pypy/dist/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rdict.py Mon Oct 24 03:00:43 2005 @@ -272,15 +272,33 @@ assert res == 14 def test_dict_inst_keys(): - class A: + class Empty: + pass + class A(Empty): pass def func(): + dic0 = {Empty(): 2} dic = {A(): 1, A(): 2} keys = dic.keys() return (isinstance(keys[1], A))*2+(isinstance(keys[0],A)) res = interpret(func, []) assert res == 3 +def test_dict_inst_iterkeys(): + class Empty: + pass + class A(Empty): + pass + def func(): + dic0 = {Empty(): 2} + dic = {A(): 1, A(): 2} + a = 0 + for k in dic.iterkeys(): + a += isinstance(k, A) + return a + res = interpret(func, []) + assert res == 2 + def test_dict_values(): def func(): dic = {' 4':1000, ' 8':200} @@ -289,7 +307,7 @@ res = interpret(func, ()) assert res == 1202 -def test_dict_inst_value(): +def test_dict_inst_values(): class A: pass def func(): @@ -299,6 +317,56 @@ res = interpret(func, []) assert res == 3 +def test_dict_inst_itervalues(): + class A: + pass + def func(): + dic = {1: A(), 2: A()} + a = 0 + for v in dic.itervalues(): + a += isinstance(v, A) + return a + res = interpret(func, []) + assert res == 2 + +def test_dict_inst_items(): + class Empty: + pass + class A: + pass + class B(Empty): + pass + def func(): + dic0 = {Empty(): 2} + dic = {B(): A(), B(): A()} + items = dic.items() + b = 0 + a = 0 + for k, v in items: + b += isinstance(k, B) + a += isinstance(v, A) + return 3*b+a + res = interpret(func, []) + assert res == 8 + +def test_dict_inst_iteritems(): + class Empty: + pass + class A: + pass + class B(Empty): + pass + def func(): + dic0 = {Empty(): 2} + dic = {B(): A(), B(): A()} + b = 0 + a = 0 + for k, v in dic.iteritems(): + b += isinstance(k, B) + a += isinstance(v, A) + return 3*b+a + res = interpret(func, []) + assert res == 8 def test_dict_items(): def func(): @@ -376,7 +444,7 @@ yield x def test_stress(): - dictrepr = rdict.DictRepr(rint.signed_repr, rint.signed_repr) + dictrepr = rdict.DictRepr(None, rint.signed_repr, rint.signed_repr) dictrepr.setup() l_dict = rdict.ll_newdict(dictrepr) referencetable = [None] * 400 From mwh at codespeak.net Mon Oct 24 12:00:28 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 24 Oct 2005 12:00:28 +0200 (CEST) Subject: [pypy-svn] r18856 - in pypy/dist/pypy/translator/asm: . ppc test Message-ID: <20051024100028.7E34D27B94@code1.codespeak.net> Author: mwh Date: Mon Oct 24 12:00:25 2005 New Revision: 18856 Added: pypy/dist/pypy/translator/asm/model.py Removed: pypy/dist/pypy/translator/asm/infregmachine.py pypy/dist/pypy/translator/asm/test/test_simulator.py Modified: pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/ppc/codegen.py pypy/dist/pypy/translator/asm/regalloc.py pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/asm/test/test_asm.py Log: substantial refactoring of the assembly generating stuff. most of the code is still there, just not where it was. the only significant change is that the comparisons copy their results into a regular register (still need to sort this out, but probably in the register allocator). Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Mon Oct 24 12:00:25 2005 @@ -1,37 +1,26 @@ import sys, os from pypy.objspace.flow.model import traverse, Block, Variable, Constant -from pypy.translator.asm import infregmachine +#from pypy.translator.asm import infregmachine from pypy.rpython.lltype import Signed from pypy.translator.asm.simulator import Machine, TranslateProgram +from pypy.translator.asm.model import * -# #Available Machine code targets (processor+operating system) -# TARGET_UNKNOWN=0 -# TARGET_PPC=1 -# TARGET_WIN386=2 - -# #set one of these -# ASM_TARGET=TARGET_UNKNOWN -# #ASM_TARGET=TARGET_WIN386 +#Available Machine code targets (processor+operating system) +TARGET_UNKNOWN=0 +TARGET_PPC=1 +TARGET_WIN386=2 # def determine_target(): -# global ASM_TARGET # if sys.platform == 'darwin': # if os.uname()[-1] == 'Power Macintosh': -# ASM_TARGET = TARGET_PPC +# return TARGET_PPC # elif sys.platform == 'win32': # if 'Intel' in sys.version: -# ASM_TARGET = TARGET_WIN386 - -# determine_target() -# if ASM_TARGET == TARGET_UNKNOWN: -# raise Exception, 'Unknown Machine-code target specified.' - -# if ASM_TARGET==TARGET_PPC: -# from pypy.translator.asm.ppcgen.ppc_assembler import PPCAssembler -# from pypy.translator.asm.ppcgen.func_builder import make_func -# elif ASM_TARGET==TARGET_WIN386: -# from pypy.translator.asm.i386gen.i386_assembler import i386Assembler as PPCAssembler #spoof system for time being -# from pypy.translator.asm.i386gen.i386_assembler import make_func +# return TARGET_WIN386 +# else: +# return TARGET_UNKNOWN +# +# ASM_TARGET = determine_target() def genasm(translator, processor): @@ -51,25 +40,23 @@ g.gencode() if processor == 'virt': + machine = Machine(g.insns) def r(*args): - return Machine.RunProgram(g.assembler.instructions, - args, - tracing=True) + return machine.execute(*args) return r elif processor == 'virtfinite': - insns = TranslateProgram(g.assembler.instructions, 50) + insns = TranslateProgram(g.insns, 50) for i in insns: print i def r(*args): return Machine.RunProgram(insns, - args, - tracing=True) + args) return r elif processor == 'ppc': from pypy.translator.asm.ppc import codegen - return codegen.make_native_code(graph, g.assembler.instructions) + return codegen.make_native_code(graph, g.insns) class FuncGenerator(object): @@ -86,10 +73,10 @@ self.blocknum[block] = len(self.blocknum) self._block_counter = 0 - self.assembler = infregmachine.Assembler() + self.insns = [] for i, var in enumerate(graph.startblock.inputargs): - self.emit('LIA', self.reg(var), Constant(i)) + self.insns.append(LOAD_ARGUMENT(self.reg(var), i)) def assign_register(self, var): assert var not in self._var2reg @@ -103,7 +90,7 @@ if isinstance(var, Constant): r = self.next_register assert isinstance(var.value, int) - self.assembler.emit("LOAD", r, var) + self.insns.append(LOAD_IMMEDIATE(r, var.value)) self.next_register += 1 return r elif isinstance(var, Variable): @@ -121,44 +108,38 @@ return 'block' + str(self.blocknum[block]) def genlinkcode(self, link): - A = self.assembler for s, t in zip(link.args, link.target.inputargs): if isinstance(s, Constant) or s.name != t.name: - A.emit('MOV', self.reg(t), self.reg(s)) - A.emit('J', self.blocktarget(link.target)) + self.insns.append(MOVE(self.reg(t), self.reg(s))) + self.insns.append(JUMP(self.blocktarget(link.target))) def genblockcode(self, block): - A = self.assembler - A.label(self.blocktarget(block)) + self.insns.append(Label(self.blocktarget(block))) assert len(block.exits) in [0, 1, 2] - ordinaryops = block.operations[:] - if len(block.exits) == 2: - assert block.exitswitch is not None - assert block.operations[-1].result is block.exitswitch - del ordinaryops[-1] - - for op in ordinaryops: - A.emit(op.opname, self.reg(op.result), *map(self.reg, op.args)) + for op in block.operations: + self.insns.append(LLInstruction( + op.opname, self.reg(op.result), *map(self.reg, op.args))) if len(block.exits) == 2: assert block.exitswitch is not None falselink, truelink = block.exits - lastop = block.operations[-1] - assert lastop.opname in ['int_gt', 'int_lt', 'int_ge', - 'int_eq', 'int_le', 'int_ne'] - A.emit(lastop.opname, *map(self.reg, lastop.args)) + assert truelink.exitcase == True + assert falselink.exitcase == False + b = self.blockname() - A.emit('JT', b) + self.insns.append(JUMP_IF_TRUE(self.reg(block.exitswitch), b)) self.genlinkcode(falselink) - A.label(b) + + self.insns.append(Label(b)) self.genlinkcode(truelink) + elif len(block.exits) == 1: self.genlinkcode(block.exits[0]) else: assert len(block.inputargs) == 1 - A.emit('RETPYTHON', self.reg(block.inputargs[0])) + self.insns.append(RETPYTHON(self.reg(block.inputargs[0]))) def gencode(self): for block in self.allblocks: Added: pypy/dist/pypy/translator/asm/model.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/model.py Mon Oct 24 12:00:25 2005 @@ -0,0 +1,263 @@ +from pypy.annotation.pairtype import extendabletype + +class Instruction(object): + __metaclass__ = extendabletype + + def registers_used(self): + return [self.target_register()] + list(self.source_registers()) + + def target_register(self): + pass + + def source_registers(self): + pass + + def renumber(self, map): + pass + + def execute(self, machine): + assert not "not here" + + def __repr__(self): + args = [] + for k, v in self.__dict__.iteritems(): + args.append('%s=%r'%(k, v)) + return '%s(%s)'%(self.__class__.__name__, ', '.join(args)) + + +class LLInstruction(Instruction): + def __init__(self, opname, dest, *sources): + self.opname = opname + self.dest = dest + self.sources = sources + + def target_register(self): + return self.dest + + def source_registers(self): + return self.sources + + def renumber(self, map): + return LLInstruction(self.opname, + map[self.dest], + *[map[s] for s in self.sources]) + + def execute(self, machine): + from pypy.rpython.llinterp import LLFrame + sources = map(machine.get_register, self.sources) + result = LLFrame.__dict__['op_' + self.opname](None, *sources) + machine.store_register(self.dest, result) + + +class LOAD_IMMEDIATE(Instruction): + def __init__(self, target, immed): + self.target = target + self.immed = immed + + def target_register(self): + return self.target + + def source_registers(self): + return [] + + def renumber(self, map): + return LOAD_IMMEDIATE(map[self.target], self.immed) + + def execute(self, machine): + machine.store_register(self.target, self.immed) + + +class LOAD_ARGUMENT(Instruction): + def __init__(self, target, argindex): + self.target = target + self.argindex = argindex + + def target_register(self): + return self.target + + def source_registers(self): + return [] + + def renumber(self, map): + return LOAD_ARGUMENT(map[self.target], self.argindex) + + def execute(self, machine): + machine.store_register(self.target, machine.args[self.argindex]) + + +class MOVE(Instruction): + def __init__(self, target, source): + self.target = target + self.source = source + + def target_register(self): + return self.target + + def source_registers(self): + return [self.source] + + def renumber(self, map): + return MOVE(map[self.target], map[self.source]) + + def execute(self, machine): + machine.store_register(self.target, machine.get_register(self.source)) + + +class RETPYTHON(Instruction): + def __init__(self, source): + self.source = source + + def target_register(self): + return None + + def source_registers(self): + return [self.source] + + def renumber(self, map): + return RETPYTHON(map[self.source]) + + def execute(self, machine): + machine.retval = machine.get_register(self.source) + machine.stopped = True + + +class ControlFlowInstruction(Instruction): + def registers_used(self): + return [] + + def target_register(self): + return None + + def source_registers(self): + return [] + + def renumber(self, map): + return self + + +class Label(ControlFlowInstruction): + def __init__(self, name): + self.name = name + + def execute(self, machine): + pass + + +class Jump(ControlFlowInstruction): + def __init__(self, target): + self.target = target + + def do_jump(self, machine): + for i, insn in enumerate(machine.insns): + print i, insn + if isinstance(insn, Label): + if insn.name == self.target: + break + else: + raise Exception, "" + machine.program_counter = i + + +class JUMP(Jump): + def execute(self, machine): + self.do_jump(machine) + + +class ConditionalJump(Jump): + def __init__(self, source, target): + self.source = source + self.target = target + + def source_registers(self): + return [self.source] + + def renumber(self, map): + return self.__class__(map[self.source], self.target) + + +class JUMP_IF_TRUE(ConditionalJump): + def execute(self, machine): + val = machine.get_register(self.source) + assert isinstance(val, bool) + if val: + self.do_jump(machine) + + +class JUMP_IF_FALSE(ConditionalJump): + def execute(self, machine): + val = machine.get_register(self.source) + assert isinstance(val, bool) + if not val: + self.do_jump(machine) + + +class STORE_STACK(Instruction): + def __init__(self, stackindex, source): + self.stackindex = stackindex + self.source = source + + def target_register(self): + return None + + def source_registers(self): + return [self.source] + + def renumber(self, map): + return STORESTACK(stackindex, map[source]) + + def execute(self, machine): + machine.stack[self.stackindex] = machine.get_register(self.source) + + +class LOAD_STACK(Instruction): + def __init__(self, target, stackindex): + self.target = target + self.stackindex = stackindex + + def target_register(self): + return self.target + + def source_registers(self): + return [] + + def renumber(self, map): + return LOADSTACK(map[self.target], self.stackindex) + + def execute(self, machine): + machine.store_register(self.target, machine.stack[self.stackindex]) + + +class Machine(object): + def __init__(self, insns, nreg=None, tracing=False): + self.insns = insns + self.nreg = nreg + self.tracing = tracing + + def execute(self, *args): + self.stopped = False + self.registers = {} + self.stack = {} + self.program_counter = 0 + self.args = args + if hasattr(self, 'retval'): + del self.retval + + while not self.stopped: + insn = self.insns[self.program_counter] + if self.tracing: + print self.program_counter, insn, + t = insn.target_register() + if t is not None: + print t, '<-', + print ', '.join(map( + str, map(self.get_register, insn.source_registers()))) + insn.execute(self) + self.program_counter += 1 + return self.retval + + def store_register(self, reg, value): + self.registers[reg] = value + + def get_register(self, reg): + return self.registers[reg] + Modified: pypy/dist/pypy/translator/asm/ppc/codegen.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppc/codegen.py (original) +++ pypy/dist/pypy/translator/asm/ppc/codegen.py Mon Oct 24 12:00:25 2005 @@ -1,14 +1,12 @@ - +from pypy.translator.asm.model import * def make_native_code(graph, infreginsns): from pypy.translator.asm.ppcgen.func_builder import make_func maxregs = 0 for insn in infreginsns: - if isinstance(insn, str): - continue for r in insn.registers_used(): maxregs = max(r, maxregs) - + from pypy.translator.asm import regalloc, simulator insns = regalloc.regalloc(infreginsns, 30) @@ -21,7 +19,7 @@ 'i'*len(graph.startblock.inputargs), maxregs) - + class PPCCodeGen(object): def assemble(self, insns): @@ -29,88 +27,107 @@ A = ppc_assembler.PPCAssembler() for i in insns: - if isinstance(i, str): - A.label(i) - continue - - getattr(self, i.name)(A, *i.arguments) + i.ppc_assemble(A) return A - def LIA(self, A, dest, argindex): - assert dest + 2 == argindex.value + 3 - - def LOAD(self, A, dest, value): - value = value.value - assert isinstance(value, int) - assert -30000 < value < 30000 - A.li(dest + 2, value) +class __extend__(LOAD_ARGUMENT): + def ppc_assemble(self, A): + assert self.target + 2 == self.argindex + 3 + +class __extend__(LOAD_IMMEDIATE): + def ppc_assemble(self, A): + assert isinstance(self.immed, int) + assert -30000 < self.immed < 30000 + A.li(self.target + 2, self.immed) + +class __extend__(Label): + def ppc_assemble(self, A): + A.label(self.name) - def JT(self, A, branch): +class __extend__(JUMP_IF_TRUE): + def ppc_assemble(self, A): # should be "A.bt(BI=0, BD=branch)" but this crashes. - A.blt(branch) + A.blt(self.target) - def J(self, A, branch): - A.b(branch) - - def RETPYTHON(self, A, reg): - A.mr(3, reg + 2) +class __extend__(JUMP): + def ppc_assemble(self, A): + A.b(self.target) + +class __extend__(RETPYTHON): + def ppc_assemble(self, A): + A.mr(3, self.source + 2) A.blr() - def MOV(self, A, dest, src): - A.mr(dest + 2, src + 2) - - def EXCH(self, A, a, b): - A.xor(a+2, a+2, b+2) - A.xor(b+2, b+2, a+2) - A.xor(a+2, a+2, b+2) - - def STORESTACK(self, A, s, v): - A.stw(v+2, 1, 24+4*s.value) - - def LOADSTACK(self, A, v, s): - A.lwz(v+2, 1, 24+4*s.value) +class __extend__(MOVE): + def ppc_assemble(self, A): + A.mr(self.target + 2, self.source + 2) + +class __extend__(STORE_STACK): + def ppc_assemble(self, A): + A.stw(self.source+2, 1, 24+4*self.stackindex) + +class __extend__(LOAD_STACK): + def ppc_assemble(self, A): + A.lwz(self.target+2, 1, 24+4*self.stackindex) + +class __extend__(LLInstruction): + def ppc_assemble(self, A): + getattr(self, self.opname)(A, self.dest+2, + *[s + 2 for s in self.sources]) def int_add(self, A, dest, a, b): - A.add(dest + 2, a + 2, b + 2) + A.add(dest, a, b) def int_sub(self, A, dest, a, b): - A.sub(dest + 2, a + 2, b + 2) + A.sub(dest, a, b) def int_mul(self, A, dest, a, b): - A.mullw(dest + 2, a + 2, b + 2) + A.mullw(dest, a, b) def int_mod(self, A, dest, a, b): - dest += 2; a += 2; b += 2 A.divw(dest, a, b) A.mullw(dest, dest, b) A.subf(dest, dest, a) def int_and(self, A, dest, a, b): - A.and_(dest + 2, a + 2, b + 2) + A.and_(dest, a, b) - def int_gt(self, A, a, b): - A.cmpw(a + 2, b + 2) + def int_gt(self, A, dest, a, b): + A.cmpw(a, b) A.crmove(0, 1) + A.mfcr(dest) + A.srwi(dest, dest, 31) + + def int_lt(self, A, dest, a, b): + A.cmpw(a, b) + A.mfcr(dest) + A.srwi(dest, dest, 31) - def int_lt(self, A, a, b): - A.cmpw(a + 2, b + 2) - - def int_ge(self, A, a, b): - A.cmpw(a + 2, b + 2) + def int_ge(self, A, dest, a, b): + A.cmpw(a, b) A.cror(0, 1, 2) + A.mfcr(dest) + A.srwi(dest, dest, 31) - def int_le(self, A, a, b): - A.cmpw(a + 2, b + 2) + def int_le(self, A, dest, a, b): + A.cmpw(a, b) A.cror(0, 0, 2) + A.mfcr(dest) + A.srwi(dest, dest, 31) - def int_eq(self, A, a, b): - A.cmpw(a + 2, b + 2) + def int_eq(self, A, dest, a, b): + A.cmpw(a, b) A.crmove(0, 2) + A.mfcr(dest) + A.srwi(dest, dest, 31) - def int_ne(self, A, a, b): - A.cmpw(a + 2, b + 2) + def int_ne(self, A, dest, a, b): + A.cmpw(a, b) A.cror(0, 0, 1) + A.mfcr(dest) + A.srwi(dest, dest, 31) + Modified: pypy/dist/pypy/translator/asm/regalloc.py ============================================================================== --- pypy/dist/pypy/translator/asm/regalloc.py (original) +++ pypy/dist/pypy/translator/asm/regalloc.py Mon Oct 24 12:00:25 2005 @@ -1,24 +1,28 @@ -from pypy.objspace.flow.model import Constant +from pypy.translator.asm.model import * def regalloc(insns, nregisters): - from pypy.translator.asm.infregmachine import Instruction - output = [] - + for insn in insns: - if isinstance(insn, str): - output.append(insn) - continue thismap = {} - for i, r in enumerate(insn.registers_used()): + i = 1 + target = insn.target_register() + if target is not None: + if not isinstance(insn, LOAD_ARGUMENT): + thismap[target] = i + i += 1 + else: + thismap[target] = target + + for r in insn.source_registers(): if r not in thismap: - if insn.name != 'LIA': - output.append(Instruction('LOADSTACK', (i+1, Constant(r)))) - thismap[r] = i+1 - else: - thismap[r] = r + output.append(LOAD_STACK(i+1, r)) + thismap[r] = i+1 + i += 1 + output.append(insn.renumber(thismap)) - for r, i in thismap.items(): - output.append(Instruction('STORESTACK', (Constant(r), i))) - + + if target is not None: + output.append(STORE_STACK(target, thismap[target])) + return output Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Mon Oct 24 12:00:25 2005 @@ -1,7 +1,7 @@ """ IRM Simulator """ import autopath from pypy.rpython.llinterp import LLFrame -from pypy.translator.asm.infregmachine import Instruction +#from pypy.translator.asm.infregmachine import Instruction from pypy.objspace.flow.model import Constant """ @@ -54,15 +54,20 @@ assert nreg>=3 ,'Some commands may use 3 registers!!!!' newprog=[] pipe=[] - old2new=range(0,totreg+1) #this must be as big as the total number of registers+1 (we start at index 1) + + # this must be as big as the total number of registers+1 (we start + # at index 1) + old2new=range(0,totreg+1) for cmd in commands: - #if we use any registers, we must possibly swap first, and then remap - if isinstance(cmd,str) or cmd.name in ('J','JT','JF'): #label or jump so pass through + # if we use any registers, we must possibly swap first, and + # then remap + if isinstance(cmd,str) or cmd.name in ('J','JT','JF'): + # label or jump so pass through newprog.append(cmd) else: - #so now remap the registers! + # so now remap the registers! regused=cmd.registers_used() t2p=[old2new[x] for x in regused] Modified: pypy/dist/pypy/translator/asm/test/test_asm.py ============================================================================== --- pypy/dist/pypy/translator/asm/test/test_asm.py (original) +++ pypy/dist/pypy/translator/asm/test/test_asm.py Mon Oct 24 12:00:25 2005 @@ -121,9 +121,9 @@ big = 1000000000 assert f(big, big) == g(big, big) -class TestAsmAfterAllocation(TestAsm): +## class TestAsmAfterAllocation(TestAsm): - processor = 'virtfinite' +## processor = 'virtfinite' class TestAsmPPC(TestAsm): From arigo at codespeak.net Mon Oct 24 16:44:28 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Oct 2005 16:44:28 +0200 (CEST) Subject: [pypy-svn] r18883 - pypy/dist/pypy/doc Message-ID: <20051024144428.524E827BA2@code1.codespeak.net> Author: arigo Date: Mon Oct 24 16:44:25 2005 New Revision: 18883 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Intermediate check-in, moving to another computer. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Mon Oct 24 16:44:25 2005 @@ -1259,11 +1259,12 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~ As the annotation process is a fix-point search, we should prove for -completeness that it is, in some sense yet to define, well-behaved. The -following proofs are all rather easy given the approach we have taken. +completeness that it is, in some sense yet to be defined, well-behaved. +The following proofs are all rather easy given the approach we have +taken. -Termination -*********** +Generalization +************** We first have to check that each rule can only turn a state *(b,E)* into a state *(b',E')* that is either identical or more general. Clearly, @@ -1272,10 +1273,10 @@ that the annotation ``b(v)`` of each variable, when modified, can only become more general. We prove it in the following order: -1. the annotations ``b(v_C.attr)`` of variables corresponding to - attributes on classes; +1. the annotations of the input variables of blocks; -2. the annotations of the input variables of blocks; +2. the annotations ``b(v_C.attr)`` of variables corresponding to + attributes on classes; 3. the annotations of the auxiliary variable of operations; @@ -1283,24 +1284,26 @@ Proof: -1. Variables corresponding to attributes of classes - - The annotation of such variables can only be modified by the - ``setattr`` rule and by being identified with other variables, - i.e. by the ``(x~y) in E`` rule. In both cases the modification - is done with a ``merge``. The latter trivially guarantees the - property of generalization, as it is based on the union operator - ``\/`` of the lattice. - -2. Input variables of blocks +1. Input variables of blocks The annotation of these variables are only modified by the - ``phi`` rule, which is based on ``merge``. + ``phi`` rule, which is based on ``merge``. The ``merge`` + operation trivially guarantees the property of generalization + because it is based on the union operator ``\/`` of the lattice. + +2. Auxiliary variables of operations + + The binding of an auxiliary variable *z'* of an operation is + never directly modified: it is only ever identified with other + variables via *E*. So ``b(z')`` is only updated by the rule + ``(z'~v) in E``, which is based on the ``merge`` operator as + well. -3. Auxiliary variables of operations +3. Variables corresponding to attributes of classes - The auxiliary variable *z'* of an operation is only ever modified - by being identified with other variables. + The annotation of such variables can only be modified by the + ``setattr`` rule (with a ``merge``) or as a result of having been + identified with other variables via *E*. We conclude as above. 4. Input and result variables of operations @@ -1314,7 +1317,7 @@ number of operations present in the block. The recurrence is based on the fact that each input variable of an operation must be either the result variable of a previous operation of the same - block or an input variable of the block. By the point 2 above, + block or an input variable of the block. By the point 1 above, if it is an input variable of the block then it can only get generalized, as desired. So the recurrence step only needs to check that if all the input variables of an operation can only be @@ -1322,7 +1325,7 @@ variable. Most cases are easy to check. Cases like ``b' = b with - (z->b(z'))`` are based on point 3 above. The only non-trivial + (z->b(z'))`` are based on point 2 above. The only non-trivial case is in the rule for ``getattr``:: b' = b with (z->lookup_filter(b(z'), C)) From arigo at codespeak.net Mon Oct 24 19:20:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Oct 2005 19:20:18 +0200 (CEST) Subject: [pypy-svn] r18889 - pypy/dist/pypy/doc Message-ID: <20051024172018.6776B27B55@code1.codespeak.net> Author: arigo Date: Mon Oct 24 19:20:16 2005 New Revision: 18889 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Finished the proof that all rules can only generalize the state. Phew! Not completely trivial. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Mon Oct 24 19:20:16 2005 @@ -657,7 +657,7 @@ * in addition, for each class ``C`` of the user program and each possible attribute name ``attr``, we add to *V* a variable called - *v_C.attr*. + ``v_C.attr``. For a function ``f`` of the user program, we call *arg_f_1, ..., arg_f_n* the variables bound to the input arguments of ``f`` (which are @@ -1260,8 +1260,8 @@ As the annotation process is a fix-point search, we should prove for completeness that it is, in some sense yet to be defined, well-behaved. -The following proofs are all rather easy given the approach we have -taken. +The following proofs are all rather straightforward given the approach +we have taken. Generalization ************** @@ -1307,54 +1307,157 @@ 4. Input and result variables of operations - First note that the result variable *z* of an operation is only - ever modified by the rule or rules specific to that operation. - This is true because *E* never identifies such a result variable - with any other variable. This allows us to check the property of + By construction of the flow graphs, the input variables of any + given operation must also appear before in the block, either as + the result variable of a previous operation, or as an input + variable of the block itself. So assume for now that the input + variables of this operation can only get generalized; we claim + that in this case the same holds for its result variable. If + this holds, then we conclude by reccurence on the number of + operations in the block: indeed, starting from point 1 above for + the input variables of the block, it shows that each result + variable -- so also all input arguments of the next operation -- + can only get generalized. + + To prove our claim, first note that none of these input and + result variables is ever identified with any other variable via + *E*: indeed, the rules described above only identify auxiliary + variables and attribute-of-class variables with each other. It + means that the only way the result variable *z* of an operation + can be modified is directly by the rule or rules specific to that + operation. This allows us to check the property of generalization on a case-by-case basis. - For a given block, we prove this point by recurrence on the - number of operations present in the block. The recurrence is - based on the fact that each input variable of an operation must - be either the result variable of a previous operation of the same - block or an input variable of the block. By the point 1 above, - if it is an input variable of the block then it can only get - generalized, as desired. So the recurrence step only needs to - check that if all the input variables of an operation can only be - generalized, then the same property holds for its result - variable. - Most cases are easy to check. Cases like ``b' = b with (z->b(z'))`` are based on point 2 above. The only non-trivial case is in the rule for ``getattr``:: - b' = b with (z->lookup_filter(b(z'), C)) - - The class ``C`` comes from the annotation ``Inst(C)`` of an input - variable. This is where the recurrence hypothesis is needed. It - is enough to prove that given annotations ``a1 <= a2`` and - ``Inst(C1) <= Inst(C2)``, we have:: - - lookup_filter(a1, Inst(C1)) <= lookup_filter(a2, Inst(C2)) - - The only interesting case is if ``a1 = Pbc(set1)`` and ``a2 = - Pbc(set2)``. In this case *set1* is a subset of *set2*. ... - - XXX first prove that the sets are "reasonable": if C.f in set, - then D.f in set for all parent classes D - - -STOP + b' = b with (z->lookup_filter(b(z'), C)) -using the previous point, this can be checked on the rule (or rules) of -each operation independently. Indeed, there are only two ways in which -``b(z)`` is modified: by ``merge .. => z``, which trivially -guarantees the property by being based on the union operator ``\/`` of -the lattice, or explicitly in a way that can easily be checked to -respect the property. + For this case, we need the following lemma: + Let ``v_C.attr`` be an attribute-of-class variable. Let + ``(b,E)`` be any state seen during the annotation process. + Assume that ``b(v_C.attr) = Pbc(set)`` where *set* is a set + containing potential bound method objects. Call *m* the + family of potential bound method objects appearing in *set*. + Then *m* has the following shape: it is "regular" in the + sense that it contains only potential bound method objects + ``D.f`` such that ``f`` is exactly the function found under + the name ``attr`` in some class ``D``; moreover, it is + "downwards-closed" in the sense that if it contains a + ``D.f``, then it also contains all ``E.g`` for all subclasses + ``E`` of ``D`` that override the method (i.e. have a function + ``g`` found under the same name ``attr``). + + Proof: + + As we have seen in `Classes and instances`_ above, the + initial binding of ``v_C.attr`` is regular and + downwards-closed by construction. Moreover, the ``setattr`` + rule explicitely checks that it is never adding any potential + bound method object to ``b(v_C.attr)``, so that the only way + such objects can be added to ``b(v_C.attr)`` is via the + identification of ``v_C.attr`` with other ``v_B.attr`` + variables, for the same name ``attr`` -- which implies that + the set *m* will always be regular. Moreover, the union of + two downwards-closed sets of potential bound method objects + is still downwards-closed. This concludes the proof. + + Let us consider the rule for ``getattr`` again:: + + b' = b with (z->lookup_filter(b(z'), C)) + + The only interesting case is when the binding ``b(z')`` is a + ``Pbc(set)`` -- more precisely, we are interested in the part *m* + of *set* that is the subset of all potential bound method + objects; the function ``lookup_filter`` is the identity on the + rest. Given that ``b(z')`` comes from ``z'`` being identified + with various ``v_C.attr`` for a fixed name ``attr``, the set *m* + is regular and downwards-closed, as we can deduce from the lemma. + + The class ``C`` in the rule for ``getattr`` comes from the + annotation ``Inst(C)`` of the first input variable of the + operation. So what we need to prove is the following: if the + binding of this input variable is generalized, and/or if the + binding of ``z'`` is generalized, then the annotation computed by + ``lookup_filter`` is also generalized (if modified at all):: + + if b(x) = Inst(C) <= b'(x) = Inst(C') + and b(z') = Pbc(set) <= b'(z') = Pbc(set') + + then lookup_filter(b(z'), C) <= lookup_filter(b'(z'), C') + + Proof: + + Call respectively *m* and *m'* the subsets of potential bound + method objects of *set* and *set'*, as above. Call *l* the + subset of *m* as computed by ``lookup_filter``, i.e.: *l* + contains all objects ``D.f`` of *m* for strict subclasses + ``D`` of ``C``, plus the single ``B.g`` coming for the most + derived non-strict superclass ``B>=C`` which appears in *m*. + (Note that as *m* is regular, it cannot actually contain + several potential bound method objects with the same class.) + Similarily for *l'* computed from *m'* and ``C'``. + + By hypothesis, *m* is contained in *m'*, but we need to check + that *l* is contained in *l'*. This is where we will use the + fact that *m* is downwards-closed. Let ``D.f`` be an element + of *l*. + + Case 1: if ``D`` is a strict subclass of ``C``, then it is + also a strict subclass of ``C'``. In this case, ``D.f``, + which also belong to *m* and thus to *m'*, also belongs to + *l'*. Graphically:: + + C' + / | \ + / | \ + / | \ + C E2 E3 + / | \ + / | \ + D1 D2 D3 + + (In this diagram, as far as they correspond to real methods, + potential bound method objects ``D1.f1``, ``D2.f2`` and + ``D3.f3`` all belong to both *l* and *l'*. The family *l'* + additionally contains ``C.g``, ``E2.h2`` and ``E3.h3``. Both + families *l* and *l'* also contain one extra item coming from + the second part of their construction rule.) + + Case 2: ``D`` is instead to most derived non-strict + superclass of ``C`` which appears in *m*; assume that ``D`` + is still a strict subclass of ``C'``. In this case, ``D.f`` + belongs to *l'* as previously. (For example, if there is a + ``C.g`` in *m*, then ``D = C`` and as seen in the above + diagram ``C.g`` is indeed in *l'*.) + + Case 3: ``D`` is still the most derived non-strict superclass + of ``C`` which appears in *m*, but this time ``D`` is not a + strict subclass of ``C'``. The situation is as follows:: + + D + | + C' + | + C + + where extra intermediate classes could be present too. To be + able to conclude that ``D.f`` is in *l'*, we now have to + prove that ``D`` is also the most derived non-strict + superclass of ``C'`` that appears in *m'*. Ab absurdo, + assume that this is not the case. Then there is a class + ``B``, strict superclass of ``C'`` but strict subclass of + ``D``, such that *m'* contains an element ``B.g``. But *m* + contains ``D.f`` and it is downwards-closed, so it must also + contain ``B.g``. This contradicts the original hypothesis on + ``D``: this ``B`` would be another more derived superclass of + ``C`` that appears in *m*. CQFD. +Termination +*********** Each basic step (execution of one rule) can lead to the generalization of the state. If it does, then other rules may be scheduled or From arigo at codespeak.net Mon Oct 24 19:37:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 24 Oct 2005 19:37:08 +0200 (CEST) Subject: [pypy-svn] r18890 - pypy/dist/pypy/doc Message-ID: <20051024173708.5D46927B55@code1.codespeak.net> Author: arigo Date: Mon Oct 24 19:37:07 2005 New Revision: 18890 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Started on soundness / most-precise-fixpoint-ness. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Mon Oct 24 19:37:07 2005 @@ -1469,18 +1469,41 @@ The extended lattice used in practice is a priori not finite. As we did not describe this lattice formally here, we have to skip the (easy) -proof that it still contains no infinite ascending chain. An ascending +proof that it still contains no infinite ascending chain (an ascending chain is a sequence where each item is strictly larger than the previous -one. +one). + Soundness ********* We define an annotation state to be *sound* if none of the rules would -lead to further Xxx. +lead to further generalization. To define this notion more formally, we +will use the following notation: let *Rules* be the set of all rules +(for the given user program). If *r* is a rule, then it can be +considered as a (mathematical) function from the set of states to the +set of states, so that "applying" the rule means computing ``(b',E') = +r( (b,E) )``. To formalize the meta-rule describing rescheduling of +rules, we introduce a third component in the state: a subset *S* of the +*Rules* which stands for the currently scheduled rules. Finally, for +any variable *v* we write *Rules_v* for the set of rules that have *v* +as an input or auxiliary variable. + +The meta-rule can be formalized as follows: we start from the initial +"meta-state" *(S,b,E)*, where *S=Rules* and *(b,E)* is the initial +state; then we apply the following meta-rule that computes a new +meta-state *(S',b',E')*:: + + pick any r in S + compute (b',E') = r( (b,E) ) + let S' = + +The meta-rule is applied repeatedly, feeding the new meta-state back +into it, until the *S* component is empty, at which point annotation is +complete and the process stops. -XXX termination + soundness + most-precise-fixpoint-ness + complexity +XXX most-precise-fixpoint-ness Complexity From pedronis at codespeak.net Mon Oct 24 21:18:18 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 24 Oct 2005 21:18:18 +0200 (CEST) Subject: [pypy-svn] r18891 - pypy/dist/pypy/objspace/std Message-ID: <20051024191818.39E5627B66@code1.codespeak.net> Author: pedronis Date: Mon Oct 24 21:18:17 2005 New Revision: 18891 Modified: pypy/dist/pypy/objspace/std/model.py Log: make it more robust in the face of w__class__ attached more diffusely. Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Mon Oct 24 21:18:17 2005 @@ -131,7 +131,8 @@ #', '.join(['%s=%r' % keyvalue for keyvalue in self.__dict__.items()]) getattr(self, 'name', '') ) - if hasattr(self, 'w__class__'): + w_cls = getattr(self, 'w__class__', None) + if w_cls is not None and w_cls is not self: s += ' instance of %s' % self.w__class__ return '<%s>' % s From pedronis at codespeak.net Mon Oct 24 21:20:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 24 Oct 2005 21:20:59 +0200 (CEST) Subject: [pypy-svn] r18892 - pypy/dist/pypy/annotation Message-ID: <20051024192059.4022727B66@code1.codespeak.net> Author: pedronis Date: Mon Oct 24 21:20:58 2005 New Revision: 18892 Modified: pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/classdef.py Log: more and stremlined annotation events Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Mon Oct 24 21:20:58 2005 @@ -388,7 +388,7 @@ if x not in self.seen_mutable: # avoid circular reflowing, # see for example test_circular_mutable_getattr self.seen_mutable[x] = True - self.annotator.policy.event(self, 'mutable', x) + self.event('mutable', x) for attr in x.__dict__: clsdef.add_source_for_attribute(attr, x) # can trigger reflowing result = SomeInstance(clsdef) @@ -738,6 +738,9 @@ def whereami(self): return self.annotator.whereami(self.position_key) + def event(self, what, x): + return self.annotator.policy.event(self, what, x) + def warning(self, msg): return self.annotator.warning(msg) Modified: pypy/dist/pypy/annotation/classdef.py ============================================================================== --- pypy/dist/pypy/annotation/classdef.py (original) +++ pypy/dist/pypy/annotation/classdef.py Mon Oct 24 21:20:58 2005 @@ -194,6 +194,8 @@ if not hasattr(value, 'class_'): value.class_ = cls # remember that this is really a method self.add_source_for_attribute(name, sources.get(name, cls), self) + if self.bookkeeper: + self.bookkeeper.event('classdef_setup', self) def add_source_for_attribute(self, attr, source, clsdef=None): """Adds information about a constant source for an attribute. From pedronis at codespeak.net Mon Oct 24 22:37:14 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 24 Oct 2005 22:37:14 +0200 (CEST) Subject: [pypy-svn] r18897 - in pypy/dist/pypy: interpreter module/thread translator translator/goal Message-ID: <20051024203714.BA56227B66@code1.codespeak.net> Author: pedronis Date: Mon Oct 24 22:37:12 2005 New Revision: 18897 Modified: pypy/dist/pypy/interpreter/baseobjspace.py pypy/dist/pypy/module/thread/os_local.py pypy/dist/pypy/translator/ann_override.py pypy/dist/pypy/translator/goal/targetpypystandalone.py Log: * use space.type consistently (so that it could possibly be overriden at annotation time) * let PyPy policy take a space to signal that we translate for the single space case Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Mon Oct 24 22:37:12 2005 @@ -29,6 +29,7 @@ space.wrap("attribute '__dict__' of %s objects " "is not writable" % typename)) + # to be used directly only by space.type implementations def getclass(self, space): return space.gettypeobject(self.typedef) 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 Mon Oct 24 22:37:12 2005 @@ -32,7 +32,7 @@ # call __init__ try: w_self = space.wrap(self) - w_type = self.getclass(space) + w_type = space.type(w_self) w_init = space.getattr(w_type, space.wrap("__init__")) space.call_args(w_init, self.initargs.prepend(w_self)) except: Modified: pypy/dist/pypy/translator/ann_override.py ============================================================================== --- pypy/dist/pypy/translator/ann_override.py (original) +++ pypy/dist/pypy/translator/ann_override.py Mon Oct 24 22:37:12 2005 @@ -9,10 +9,11 @@ class PyPyAnnotatorPolicy(AnnotatorPolicy): allow_someobjects = False - def __init__(pol): + def __init__(pol, single_space=None): pol.lookups = {} pol.lookups_where = {} pol.pypytypes = {} + pol.single_space = single_space def override__wrap_exception_cls(pol, space, x): import pypy.objspace.std.typeobject as typeobject @@ -125,7 +126,7 @@ CACHED_LOOKUP = """ def lookup_%(attr)s(space, w_obj, name): - w_type = w_obj.getclass(space) + w_type = space.type(w_obj) if not w_type.is_heaptype(): return w_type.cached_%(attr)s return w_type.lookup("%(attr)s") Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Mon Oct 24 22:37:12 2005 @@ -79,5 +79,5 @@ res = entry_point(["pypy", "app_basic_example.py"]) assert res == 0 - return entry_point, None, PyPyAnnotatorPolicy() + return entry_point, None, PyPyAnnotatorPolicy(single_space = space) From afa at codespeak.net Tue Oct 25 02:00:06 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 25 Oct 2005 02:00:06 +0200 (CEST) Subject: [pypy-svn] r18900 - pypy/dist/pypy/translator/c/src Message-ID: <20051025000006.AE46A27B60@code1.codespeak.net> Author: afa Date: Tue Oct 25 02:00:02 2005 New Revision: 18900 Modified: pypy/dist/pypy/translator/c/src/ll_os.h Log: Corrected a compilation warning on Windows, and almost a bug: a pointer should not be compared with a char. But no visible effect: on Windows, a path like "c:\\/\\temp\\///*" is equivalent to "c:/temp/*" 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 Tue Oct 25 02:00:02 2005 @@ -280,7 +280,6 @@ } /******************** opendir/readdir/closedir ********************/ - #if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR) /* emulation of opendir, readdir, closedir */ @@ -314,9 +313,10 @@ DIR *d = malloc(sizeof(DIR) + lng + 4); if (d != NULL) { - strcpy(&d->arg, dirname); - strcpy(&d->arg + lng, "\\*.*" + (&d->arg + lng - 1 == '\\')); - d->hFind = FindFirstFile(&d->arg, &d->FileData); + char *ptr = (char*)d->arg; + strcpy(ptr, dirname); + strcpy(ptr + lng, "\\*.*" + (*(ptr + lng - 1) == '\\')); + d->hFind = FindFirstFile(ptr, &d->FileData); d->d_name = d->FileData.cFileName; if (d->hFind == INVALID_HANDLE_VALUE) { d->d_name = NULL; From afa at codespeak.net Tue Oct 25 02:52:08 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 25 Oct 2005 02:52:08 +0200 (CEST) Subject: [pypy-svn] r18901 - in pypy/dist/pypy: module/_socket module/_socket/rpython module/_socket/rpython/test translator/c translator/c/src translator/c/test Message-ID: <20051025005208.B0E1527B60@code1.codespeak.net> Author: afa Date: Tue Oct 25 02:51:56 2005 New Revision: 18901 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/rpython/exttable.py pypy/dist/pypy/module/_socket/rpython/ll__socket.py pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll__socket.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Implemented socket.getaddrinfo() - Only support for ipv4 addresses - Hard, because I need 2 structures: an opaque object that works as an iterator, and a tuple to get each result. - Each string is IncRef'd twice: in RPyString_FromString, and when inserted into the tuple. Is there a way to DecRef a rstring from custom C code? I had to mark the test "in-progress" because of this. - There must be an easier way. For example, ll__socket.ADDRINFO_RESULT and exttable.ann_addrinfo should come from a unique source. Comments are welcome! - This line, and those below, will be ignored-- M pypy/module/_socket/interp_socket.py M pypy/module/_socket/rpython/test/test_ll__socket.py M pypy/module/_socket/rpython/exttable.py M pypy/module/_socket/rpython/ll__socket.py M pypy/translator/c/test/test_extfunc.py M pypy/translator/c/src/ll__socket.h M pypy/translator/c/extfunc.py Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Tue Oct 25 02:51:56 2005 @@ -4,6 +4,7 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.gateway import W_Root, NoneNotWrapped from pypy.interpreter.gateway import ObjSpace, interp2app +from pypy.module._socket.rpython import rsocket if sys.platform == 'win32': WIN32_ERROR_MESSAGES = { @@ -325,25 +326,53 @@ raise wrap_socketerror(space, e) inet_ntop.unwrap_spec = [ObjSpace, int, str] +def enumerateaddrinfo(space, addr): + result = [] + while addr.nextinfo(): + info = (addr.family, addr.socktype, addr.proto, + addr.canonname, addr.sockaddr) + result.append(space.wrap(info)) + return space.newlist(result) + def getaddrinfo(space, w_host, w_port, family=0, socktype=0, proto=0, flags=0): """getaddrinfo(host, port [, family, socktype, proto, flags]) -> list of (family, socktype, proto, canonname, sockaddr) Resolve host and port into addrinfo struct. """ - if space.is_true(space.isinstance(w_host, space.w_unicode)): - w_host = space.call_method(w_host, "encode", space.wrap("idna")) - host = space.unwrap(w_host) + # host can be None, string or unicode + if space.is_w(w_host, space.w_None): + host = None + elif space.is_true(space.isinstance(w_host, space.w_str)): + host = space.str_w(w_host) + elif space.is_true(space.isinstance(w_host, space.w_unicode)): + w_shost = space.call_method(w_host, "encode", space.wrap("idna")) + host = space.str_w(w_shost) + else: + raise OperationError(space.w_TypeError, + space.wrap( + "getaddrinfo() argument 1 must be string or None")) - if space.is_true(space.isinstance(w_port, space.w_int)): + # port can be None, int or string + if space.is_w(w_port, space.w_None): + port = None + elif space.is_true(space.isinstance(w_port, space.w_int)): port = str(space.int_w(w_port)) - else: + elif space.is_true(space.isinstance(w_port, space.w_str)): port = space.str_w(w_port) + else: + raise OperationError(space.w_TypeError, + space.wrap("Int or String expected")) try: - return space.wrap(socket.getaddrinfo(host, port, family, socktype, proto, flags)) + addr = rsocket.getaddrinfo(host, port, family, socktype, proto, flags) except socket.error, e: raise wrap_socketerror(space, e) + + try: + return enumerateaddrinfo(space, addr) + finally: + addr.free() getaddrinfo.unwrap_spec = [ObjSpace, W_Root, W_Root, int, int, int, int] def getnameinfo(space, w_sockaddr, flags): Modified: pypy/dist/pypy/module/_socket/rpython/exttable.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/exttable.py (original) +++ pypy/dist/pypy/module/_socket/rpython/exttable.py Tue Oct 25 02:51:56 2005 @@ -3,15 +3,38 @@ """ import _socket -from pypy.rpython.extfunctable import declare +from pypy.module._socket.rpython import rsocket +from pypy.rpython.extfunctable import declare, declareptrtype +from pypy.annotation.model import Constant, SomeTuple, SomeList, SomeInteger, SomeString +from pypy.annotation.listdef import ListDef +from pypy.annotation.model import unionof module = 'pypy.module._socket.rpython.ll__socket' # ____________________________________________________________ # Built-in functions needed in the rtyper +def ann_addrinfo(*s_args): + # Address info is a tuple: (family, socktype, proto, canonname, sockaddr) + # where sockaddr is either a 2-tuple or a 4-tuple + addrinfo = SomeTuple([SomeInteger(), + SomeInteger(), + SomeInteger(), + SomeString(), + SomeString(), + SomeInteger(), + SomeInteger(), + SomeInteger(), + ]) + return addrinfo + declare(_socket.gethostname, str, '%s/gethostname' % module) +declare(rsocket.getaddrinfo, rsocket.ADDRINFO, '%s/getaddrinfo' % module) +declareptrtype(rsocket.ADDRINFO, "ADDRINFO", + nextinfo = (ann_addrinfo, '%s/nextaddrinfo' % module), + free = (type(None), '%s/freeaddrinfo' % module)) + declare(_socket.ntohs, int, '%s/ntohs' % module) declare(_socket.htons, int, '%s/ntohs' % module) declare(_socket.ntohl, int, '%s/ntohl' % module) Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Tue Oct 25 02:51:56 2005 @@ -1,11 +1,58 @@ import _socket -from pypy.rpython.module.support import to_rstr +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 +from pypy.rpython.module.support import to_opaque_object, from_opaque_object +from pypy.module._socket.rpython import rsocket def ll__socket_gethostname(): return to_rstr(_socket.gethostname()) ll__socket_gethostname.suggested_primitive = True +def ll__socket_getaddrinfo(host, port, family, socktype, proto, flags): + addr = rsocket.getaddrinfo(from_rstr(host), port, + family, socktype, proto, flags) + return to_opaque_object(addr) +ll__socket_getaddrinfo.suggested_primitive = True + + +# XXX The tag and the items names must have the same name as +# the structure computed from ann_addrinfo +ADDRINFO_RESULT = GcStruct('tuple8', + ('item0', Signed), + ('item1', Signed), + ('item2', Signed), + ('item3', Ptr(STR)), + ('item4', Ptr(STR)), + ('item5', Signed), + ('item6', Signed), + ('item7', Signed), + ) + +def ll__socket_addrinfo(family, socktype, proto, canonname, + ipaddr, port, flowinfo, scopeid): + tup = malloc(ADDRINFO_RESULT) + tup.item0 = family + tup.item1 = socktype + tup.item2 = proto + tup.item3 = canonname + tup.item4 = ipaddr + tup.item5 = port + tup.item6 = flowinfo # ipV6 + tup.item7 = scopeid # ipV6 + return tup + +def ll__socket_nextaddrinfo(opaqueaddr): + addr = from_opaque_object(opaqueaddr) + return addr.nextinfo() +ll__socket_nextaddrinfo.suggested_primitive = True + +def ll__socket_freeaddrinfo(opaqueaddr): + addr = from_opaque_object(opaqueaddr) + return addr.free() +ll__socket_freeaddrinfo.suggested_primitive = True + def ll__socket_ntohs(htons): return _socket.ntohs(htons) ll__socket_ntohs.suggested_primitive = True Modified: pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/test/test_ll__socket.py Tue Oct 25 02:51:56 2005 @@ -5,6 +5,7 @@ from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.module.support import from_rstr +from pypy.rpython.module.support import to_opaque_object, from_opaque_object def test_ntohs(): def fn(): @@ -19,3 +20,12 @@ a = RPythonAnnotator() res = interpret(fn, []) assert from_rstr(res) == _socket.gethostname() + +def test_getaddrinfo(): + host = "localhost" + port = 25 + result = [] + addr = ll__socket_getaddrinfo(to_rstr(host), port, 0, 0, 0, 0) + info = ll__socket_nextaddrinfo(addr) + info = info[:4] + (info[4:],) + assert info == _socket.getaddrinfo(host, port)[0] Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Oct 25 02:51:56 2005 @@ -58,6 +58,9 @@ ll_stack.ll_stack_unwind: 'LL_stack_unwind', ll_stack.ll_stack_too_big: 'LL_stack_too_big', ll__socket.ll__socket_gethostname: 'LL__socket_gethostname', + ll__socket.ll__socket_getaddrinfo: 'LL__socket_getaddrinfo', + ll__socket.ll__socket_nextaddrinfo: 'LL__socket_nextaddrinfo', + ll__socket.ll__socket_freeaddrinfo: 'LL__socket_freeaddrinfo', ll__socket.ll__socket_ntohs: 'LL__socket_ntohs', ll__socket.ll__socket_htons: 'LL__socket_htons', ll__socket.ll__socket_htonl: 'LL__socket_htonl', @@ -85,6 +88,7 @@ yield ('RPyFREXP_RESULT', ll_math.FREXP_RESULT) yield ('RPyMODF_RESULT', ll_math.MODF_RESULT) yield ('RPySTAT_RESULT', ll_os.STAT_RESULT) + yield ('RPySOCKET_ADDRINFO', ll__socket.ADDRINFO_RESULT) def predeclare_utility_functions(db, rtyper): # Common utility functions @@ -123,6 +127,10 @@ yield annotate(ll_math.ll_modf_result, lltype.Float, lltype.Float) yield annotate(ll_os.ll_stat_result, *([lltype.Signed] * 10)) + args = [lltype.Signed, lltype.Signed, lltype.Signed, lltype.Ptr(STR), + lltype.Ptr(STR), lltype.Signed, lltype.Signed, lltype.Signed] + yield annotate(ll__socket.ll__socket_addrinfo, *args) + def predeclare_extfuncs(db, rtyper): for func, funcobj in db.externalfuncs.items(): c_name = EXTERNALS[func] Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Tue Oct 25 02:51:56 2005 @@ -9,41 +9,40 @@ int LL__socket_htons(int ntohs); long LL__socket_ntohl(long htonl); long LL__socket_htonl(long ntohl); +struct RPyOpaque_ADDRINFO *LL__socket_getaddrinfo(RPyString *host, RPyString *port, + int family, int socktype, + int proto, int flags); +RPySOCKET_ADDRINFO *LL__socket_nextaddrinfo(struct RPyOpaque_ADDRINFO *addr); #ifndef PYPY_NOT_MAIN_FILE +#ifdef MS_WINDOWS +# include +#endif int LL__socket_ntohs(int htons) { - return (int)ntohs((short) htons); - } int LL__socket_htons(int ntohs) { - return (int)htons((short) ntohs); - } long LL__socket_ntohl(long htonl) { - return ntohl(htonl); - } long LL__socket_htonl(long ntohl) { - return htonl(ntohl); - } RPyString *LL__socket_gethostname() { char buf[1024]; - char *res; + int res; res = gethostname(buf, sizeof buf - 1); if (res < 0) { //XXX @@ -56,4 +55,78 @@ return RPyString_FromString(buf); } +struct RPyOpaque_ADDRINFO { + struct addrinfo *info0; + struct addrinfo *info; +}; + +struct RPyOpaque_ADDRINFO *LL__socket_getaddrinfo(RPyString *host, RPyString *port, + int family, int socktype, + int proto, int flags) +{ + struct addrinfo hints; + struct addrinfo *res0; + struct RPyOpaque_ADDRINFO *addr; + int error; + char *hptr = RPyString_AsString(host); + char *pptr = RPyString_AsString(port); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = family; + hints.ai_socktype = socktype; + hints.ai_protocol = proto; + hints.ai_flags = flags; + error = getaddrinfo(hptr, pptr, &hints, &res0); + addr = malloc(sizeof (struct RPyOpaque_ADDRINFO)); + addr->info0 = res0; + addr->info = res0; + return addr; +} + +RPyString *makeipaddr(struct sockaddr *addr) +{ + char buf[NI_MAXHOST]; + int error; + + error = getnameinfo(addr, sizeof (struct sockaddr), buf, sizeof(buf), NULL, 0, + NI_NUMERICHOST); + if (error) { + return RPyString_FromString("Error"); // XXX + } + return RPyString_FromString(buf); +} + +RPySOCKET_ADDRINFO *LL__socket_nextaddrinfo(struct RPyOpaque_ADDRINFO *addr) +{ + struct addrinfo *info = addr->info; + + if( !info ) + return ll__socket_addrinfo(0,0,0,NULL,NULL,0,0,0); + + addr->info = addr->info->ai_next; + + { + RPySOCKET_ADDRINFO *ret; + struct sockaddr_in *a = (struct sockaddr_in *)info->ai_addr; + + RPyString *canonname = RPyString_FromString( + info->ai_canonname?info->ai_canonname:""); + RPyString *ipaddr = makeipaddr(info->ai_addr); + + ret = ll__socket_addrinfo(info->ai_family, + info->ai_socktype, + info->ai_protocol, + canonname, + ipaddr, // XXX AF_INET Only! + ntohs(a->sin_port),0,0); + // XXX DECREF(canonname) + // XXX DECREF(ipaddr) + } +} + +void LL__socket_freeaddrinfo(struct RPyOpaque_ADDRINFO *addr) +{ + freeaddrinfo(addr->info0); + free(addr2); +} #endif 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 Oct 25 02:51:56 2005 @@ -562,3 +562,24 @@ res = f1() assert res == _socket.gethostname() +def test_getaddrinfo(): + #py.test.skip("In progress") + # XXX fails on 'assert mallocs == frees' + # needs a way to decref rstrings from ll__socket.h + import pypy.module._socket.rpython.exttable # for declare()/declaretype() + from pypy.module._socket.rpython import rsocket + def does_stuff(host, port): + addr = rsocket.getaddrinfo(host, port, 0, 0, 0, 0) + result = [] + while True: + info = addr.nextinfo() + if info[0] == 0: + break + result.append("(%d, %d, %d, '%s', ('%s', %d))" % + (info[0],info[1],info[2],info[3],info[4],info[5])) + addr.free() + return str(result) + f1 = compile(does_stuff, [str, str]) + res = f1("localhost", "25") + assert eval(res) == _socket.getaddrinfo("localhost", "25") + From pedronis at codespeak.net Tue Oct 25 03:40:11 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 25 Oct 2005 03:40:11 +0200 (CEST) Subject: [pypy-svn] r18902 - pypy/dist/pypy/translator/tool Message-ID: <20051025014011.32B9427B61@code1.codespeak.net> Author: pedronis Date: Tue Oct 25 03:40:10 2005 New Revision: 18902 Modified: pypy/dist/pypy/translator/tool/util.py Log: make fork before rtype work again Modified: pypy/dist/pypy/translator/tool/util.py ============================================================================== --- pypy/dist/pypy/translator/tool/util.py (original) +++ pypy/dist/pypy/translator/tool/util.py Tue Oct 25 03:40:10 2005 @@ -26,7 +26,7 @@ def assert_rtyper_not_imported(): prefix = 'pypy.rpython.' oknames = ('rarithmetic memory memory.lladdress extfunctable ' - 'lltype objectmodel error ros'.split()) + 'lltype objectmodel error ros ootypesystem ootypesystem.ootype'.split()) wrongimports = [] for name, module in sys.modules.items(): if module is not None and name.startswith(prefix): From cfbolz at codespeak.net Tue Oct 25 10:39:26 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Tue, 25 Oct 2005 10:39:26 +0200 (CEST) Subject: [pypy-svn] r18908 - pypy/dist/pypy/tool Message-ID: <20051025083926.A3D3227B61@code1.codespeak.net> Author: cfbolz Date: Tue Oct 25 10:39:25 2005 New Revision: 18908 Modified: pypy/dist/pypy/tool/statistic_over_time.py Log: bugfix. there is another problem, though: I cannot easily check out an old version since there is an old external that points to a repository that does not exist any more. Modified: pypy/dist/pypy/tool/statistic_over_time.py ============================================================================== --- pypy/dist/pypy/tool/statistic_over_time.py (original) +++ pypy/dist/pypy/tool/statistic_over_time.py Tue Oct 25 10:39:25 2005 @@ -12,13 +12,10 @@ tempdir = py.path.svnwc(py.test.ensuretemp("pypy-dist")) print "checking out" -tempdir.checkout(URL) +tempdir.checkout(URL, 8500) print "done" pypy = tempdir.join('pypy') -class DailyStatistic(object): - pass - statistic = [] curr_rev = tempdir.info().rev @@ -43,14 +40,14 @@ except: tempdir.localpath.remove(1) tempdir.localpath.mkdir() - if curr_rev < 8359: - URL = "http://codespeak.net/svn/pypy/trunk" while 1: + if curr_rev < 8359: + URL = "http://codespeak.net/svn/pypy/trunk" try: tempdir.checkout(URL, rev=curr_rev - 1) except KeyboardInterrupt: raise - except: + except Exception, e: curr_rev -= 1 else: break From mwh at codespeak.net Tue Oct 25 11:33:34 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 25 Oct 2005 11:33:34 +0200 (CEST) Subject: [pypy-svn] r18910 - pypy/extradoc/talk Message-ID: <20051025093334.058D827B5C@code1.codespeak.net> Author: mwh Date: Tue Oct 25 11:33:34 2005 New Revision: 18910 Added: pypy/extradoc/talk/pycon2006-submission.txt (contents, props changed) Log: first draft of a pycon talk proposal. Added: pypy/extradoc/talk/pycon2006-submission.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2006-submission.txt Tue Oct 25 11:33:34 2005 @@ -0,0 +1,38 @@ +Author Names +------------ + +(from) Michael Hudson, Holger Krekel, Armin Rigo, Christian Tismer + +Contact Information +------------------- + +pypy-dev? + +Requested Timeslot +------------------ + +45 minutes? Or two 30 minutes? Or? + +Summary of proposed presentation +-------------------------------- + +I guess the main progress has been on translation stuff (rtyper, etc) +since the last pycon. + +Presentation Outline +-------------------- + +Something like: + +- Introduction to PyPy +- Overview (with the fruit object space again? :) +- Where we are now +- What we do next +- ... +- Profit! + +Intended audience +----------------- + +Anyone interested, talk should be accessible to anyone who knows +Python reasonably well. From mwh at codespeak.net Tue Oct 25 11:49:30 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 25 Oct 2005 11:49:30 +0200 (CEST) Subject: [pypy-svn] r18913 - pypy/extradoc/talk Message-ID: <20051025094930.3251B27B7A@code1.codespeak.net> Author: mwh Date: Tue Oct 25 11:49:29 2005 New Revision: 18913 Modified: pypy/extradoc/talk/pycon2006-submission.txt Log: more words. perhaps it would be best to offer two 30 minute talks -- a propellor-heads one and one about how the project works? Modified: pypy/extradoc/talk/pycon2006-submission.txt ============================================================================== --- pypy/extradoc/talk/pycon2006-submission.txt (original) +++ pypy/extradoc/talk/pycon2006-submission.txt Tue Oct 25 11:49:29 2005 @@ -16,8 +16,11 @@ Summary of proposed presentation -------------------------------- -I guess the main progress has been on translation stuff (rtyper, etc) -since the last pycon. +PyPy, the notorious Python-in-Python project reached a significant +milestone in the summer of 2005: being able to produce a standalone +python interpreter with no dependencies on any of CPython's C code. +This talk will describe the toolchain that got us to this point and +what we plan on doing with it next. Presentation Outline -------------------- @@ -25,11 +28,11 @@ Something like: - Introduction to PyPy +- Demo of pypy-c. - Overview (with the fruit object space again? :) -- Where we are now -- What we do next -- ... -- Profit! +- Our toolchain: the annotator, the rtyper, the backends. +- Future plans: JIT, logic programming, other backends. +- About the project: The EU, sprints, TDD, etc. Intended audience ----------------- From arigo at codespeak.net Tue Oct 25 12:09:00 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Oct 2005 12:09:00 +0200 (CEST) Subject: [pypy-svn] r18914 - pypy/dist/pypy/module/stackless Message-ID: <20051025100900.69A3227B66@code1.codespeak.net> Author: arigo Date: Tue Oct 25 12:08:59 2005 New Revision: 18914 Removed: pypy/dist/pypy/module/stackless/ Log: Removed this experiment. From arigo at codespeak.net Tue Oct 25 12:26:41 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Oct 2005 12:26:41 +0200 (CEST) Subject: [pypy-svn] r18918 - pypy/dist/pypy/translator/c/src Message-ID: <20051025102641.BD63027B69@code1.codespeak.net> Author: arigo Date: Tue Oct 25 12:26:41 2005 New Revision: 18918 Modified: pypy/dist/pypy/translator/c/src/ll__socket.h Log: * Linux compabitibility * 'addr2' undeclared? I suppose that 'addr' what meant here Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Tue Oct 25 12:26:41 2005 @@ -3,12 +3,16 @@ # pragma comment(lib, "ws2_32.lib") #else # include +# include +# include +# include #endif int LL__socket_ntohs(int htons); int LL__socket_htons(int ntohs); long LL__socket_ntohl(long htonl); long LL__socket_htonl(long ntohl); +RPyString *LL__socket_gethostname(void); struct RPyOpaque_ADDRINFO *LL__socket_getaddrinfo(RPyString *host, RPyString *port, int family, int socktype, int proto, int flags); @@ -39,7 +43,7 @@ return htonl(ntohl); } -RPyString *LL__socket_gethostname() +RPyString *LL__socket_gethostname(void) { char buf[1024]; int res; @@ -121,12 +125,13 @@ ntohs(a->sin_port),0,0); // XXX DECREF(canonname) // XXX DECREF(ipaddr) + return ret; } } void LL__socket_freeaddrinfo(struct RPyOpaque_ADDRINFO *addr) { freeaddrinfo(addr->info0); - free(addr2); + free(addr); } #endif From arigo at codespeak.net Tue Oct 25 12:31:51 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Oct 2005 12:31:51 +0200 (CEST) Subject: [pypy-svn] r18919 - pypy/extradoc/sprintinfo/paris Message-ID: <20051025103151.E58C327B82@code1.codespeak.net> Author: arigo Date: Tue Oct 25 12:31:51 2005 New Revision: 18919 Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Log: Renamed "continuations" to "frame_stack_top", as per pypy-dev discussion. Modified: pypy/extradoc/sprintinfo/paris/stackless-discussion.txt ============================================================================== --- pypy/extradoc/sprintinfo/paris/stackless-discussion.txt (original) +++ pypy/extradoc/sprintinfo/paris/stackless-discussion.txt Tue Oct 25 12:31:51 2005 @@ -91,57 +91,57 @@ enough to implement, say, app-level greenlets or tasklets as a mixed module. -We introduce an RPython type ``continuation`` and a built-in function -``yield_continuation()`` that work as follows (see example below): +We introduce an RPython type ``frame_stack_top`` and a built-in function +``yield_current_frame_to_caller()`` that work as follows (see example below): -* The built-in function ``yield_continuation()`` causes the current - function's state to be captured in a new ``continuation`` object that - is returned to the parent. Only one frame, the current one, is - captured this way. The current frame is suspended and the caller - continues to run. Note that the caller is only resumed once: when - ``yield_continuation()`` is called. See below. +* The built-in function ``yield_current_frame_to_caller()`` causes the current + function's state to be captured in a new ``frame_stack_top`` object that is + returned to the parent. Only one frame, the current one, is captured this + way. The current frame is suspended and the caller continues to run. Note + that the caller is only resumed once: when + ``yield_current_frame_to_caller()`` is called. See below. -* A ``continuation`` object can be jumped to by calling its ``switch()`` +* A ``frame_stack_top`` object can be jumped to by calling its ``switch()`` method with no argument. -* ``yield_continuation()`` and ``switch()`` themselves return a new - ``continuation`` object: the freshly captured state of the caller of - the source ``switch()`` that was just executed, or None in the case - described below. - -* the function that called ``yield_continuation()`` also has a normal - return statement, like all functions. This statement must return - another ``continuation`` object. The latter is *not* returned to the - original caller; there is no way to return several times to the - caller. Instead, it designates the place to which the execution must - jump, as if by a ``switch()``. The place to which we jump this way - will see a None as the source continuation. +* ``yield_current_frame_to_caller()`` and ``switch()`` themselves return a new + ``frame_stack_top`` object: the freshly captured state of the caller of the + source ``switch()`` that was just executed, or None in the case described + below. + +* the function that called ``yield_current_frame_to_caller()`` also has a + normal return statement, like all functions. This statement must return + another ``frame_stack_top`` object. The latter is *not* returned to the + original caller; there is no way to return several times to the caller. + Instead, it designates the place to which the execution must jump, as if by + a ``switch()``. The place to which we jump this way will see a None as the + source frame stack top. -* every continuation must be resumed once and only once. Not resuming +* every frame stack top must be resumed once and only once. Not resuming it at all causes a leak. Resuming it several times causes a crash. -* a function that called ``yield_continuation()`` should not raise. It - would have no implicit continuation to propagate the exception to. - That would be a crashingly bad idea. +* a function that called ``yield_current_frame_to_caller()`` should not raise. + It would have no implicit parent frame to propagate the exception to. That + would be a crashingly bad idea. The following example would print the numbers from 1 to 7 in order:: def g(): print 2 - cont_before_5 = yield_continuation() + frametop_before_5 = yield_current_frame_to_caller() print 4 - cont_before_7 = cont_before_5.switch() + frametop_before_7 = frametop_before_5.switch() print 6 - return cont_before_7 + return frametop_before_7 def f(): print 1 - cont_before_4 = g() + frametop_before_4 = g() print 3 - cont_before_6 = cont_before_4.switch() + frametop_before_6 = frametop_before_4.switch() print 5 - cont_after_return = cont_before_6.switch() + frametop_after_return = frametop_before_6.switch() print 7 - assert cont_after_return is None + assert frametop_after_return is None f() From afa at codespeak.net Tue Oct 25 13:30:41 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 25 Oct 2005 13:30:41 +0200 (CEST) Subject: [pypy-svn] r18927 - in pypy/dist/pypy: module/_socket/rpython translator/c/test Message-ID: <20051025113041.C56C227B69@code1.codespeak.net> Author: afa Date: Tue Oct 25 13:30:39 2005 New Revision: 18927 Added: pypy/dist/pypy/module/_socket/rpython/rsocket.py Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Oops, forgot one file. Added: pypy/dist/pypy/module/_socket/rpython/rsocket.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/module/_socket/rpython/rsocket.py Tue Oct 25 13:30:39 2005 @@ -0,0 +1,26 @@ +""" +Helper file for Python equivalents of os specific calls. +""" + +import socket + +class ADDRINFO(object): + def __init__(self, host, port, family, socktype, proto, flags): + self._entries = iter(socket.getaddrinfo( + host, port, family, socktype, proto, flags)) + + def nextinfo(self): + try: + info = self._entries.next() + except StopIteration: + return None + (self.family, self.socktype, self.proto, + self.canonname, self.sockaddr) = info + return info[:4] + info[4] + + def free(self): + pass + + +def getaddrinfo(host, port, family, socktype, proto, flags): + return ADDRINFO(host, port, family, socktype, proto, flags) 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 Oct 25 13:30:39 2005 @@ -563,7 +563,7 @@ assert res == _socket.gethostname() def test_getaddrinfo(): - #py.test.skip("In progress") + py.test.skip("In progress") # XXX fails on 'assert mallocs == frees' # needs a way to decref rstrings from ll__socket.h import pypy.module._socket.rpython.exttable # for declare()/declaretype() From arigo at codespeak.net Tue Oct 25 13:32:18 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Tue, 25 Oct 2005 13:32:18 +0200 (CEST) Subject: [pypy-svn] r18928 - in pypy/dist/pypy: annotation rpython rpython/module translator translator/c translator/c/src translator/c/test Message-ID: <20051025113218.3EF9927B69@code1.codespeak.net> Author: arigo Date: Tue Oct 25 13:32:15 2005 New Revision: 18928 Added: pypy/dist/pypy/rpython/rstack.py pypy/dist/pypy/translator/c/test/test_stackless.py - copied, changed from r18743, pypy/dist/pypy/translator/c/test/test_standalone.py Modified: pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/module/ll_stack.py pypy/dist/pypy/rpython/module/ll_stackless.py pypy/dist/pypy/rpython/objectmodel.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rspecialcase.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll_stackless.h pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/test/test_standalone.py pypy/dist/pypy/translator/transform.py Log: Capturing stack frame tops: * yield_current_frame_to_caller() as described in http://codespeak.net/svn/pypy/extradoc/sprintinfo/paris/stackless-discussion.txt * the existing and the new RPython functions about stack manipulation are now in their own rpython/rstack.py * yield_current_frame_to_caller() turns into a low-level operation of the same name, which is special-cased by translator/c/stackless.py * moved the stackless tests in their own translator/c/test/test_stackless.py * C implementation: the 'yield_current_frame_to_caller' operation triggers a stack unwind but doesn't propagate the unwind exception -- instead, it grabs the new stack top, link it a bit to make it stand-alone, and returns it to the caller. The switch() method of frame_stack_top objects unwinds the current stack completely and then sets the global variables in a state that fools the main loop into thinking that the next frame to run is precisely the one we are trying to switch to. Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Tue Oct 25 13:32:15 2005 @@ -9,12 +9,14 @@ from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress from pypy.annotation.model import SomeFloat, unionof from pypy.annotation.model import SomePBC, SomeInstance, SomeDict +from pypy.annotation.model import SomeExternalObject from pypy.annotation.model import annotation_to_lltype, lltype_to_annotation from pypy.annotation.model import add_knowntypedata from pypy.annotation.bookkeeper import getbookkeeper from pypy.objspace.flow.model import Constant import pypy.rpython.rarithmetic import pypy.rpython.objectmodel +import pypy.rpython.rstack # convenience only! def immutablevalue(x): @@ -256,6 +258,9 @@ def robjmodel_keepalive_until_here(*args_s): return immutablevalue(None) + +def rstack_yield_current_frame_to_caller(): + return SomeExternalObject(pypy.rpython.rstack.frame_stack_top) ##def rarith_ovfcheck(s_obj): @@ -299,6 +304,8 @@ BUILTIN_ANALYZERS[pypy.rpython.objectmodel.r_dict] = robjmodel_r_dict BUILTIN_ANALYZERS[pypy.rpython.objectmodel.hlinvoke] = robjmodel_hlinvoke BUILTIN_ANALYZERS[pypy.rpython.objectmodel.keepalive_until_here] = robjmodel_keepalive_until_here +BUILTIN_ANALYZERS[pypy.rpython.rstack.yield_current_frame_to_caller] = ( + rstack_yield_current_frame_to_caller) BUILTIN_ANALYZERS[Exception.__init__.im_func] = exception_init BUILTIN_ANALYZERS[OSError.__init__.im_func] = exception_init Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Tue Oct 25 13:32:15 2005 @@ -221,11 +221,14 @@ # ___________________________________________________________ # stackless -from pypy.rpython import objectmodel -declare(objectmodel.stack_frames_depth, int, 'll_stackless/stack_frames_depth') -declare(objectmodel.stack_too_big, bool, 'll_stack/too_big') -declare(objectmodel.stack_check, noneannotation, 'll_stack/check') -declare(objectmodel.stack_unwind, noneannotation, 'll_stack/unwind') +from pypy.rpython import rstack +declare(rstack.stack_frames_depth, int, 'll_stackless/stack_frames_depth') +declare(rstack.stack_too_big, bool, 'll_stack/too_big') +declare(rstack.stack_check, noneannotation, 'll_stack/check') +declare(rstack.stack_unwind, noneannotation, 'll_stack/unwind') +frametop_type_info = declareptrtype(rstack.frame_stack_top, 'frame_stack_top', + switch = (rstack.frame_stack_top, + 'll_stackless/switch')) # ___________________________________________________________ # the exceptions that can be implicitely raised by some operations Modified: pypy/dist/pypy/rpython/module/ll_stack.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_stack.py (original) +++ pypy/dist/pypy/rpython/module/ll_stack.py Tue Oct 25 13:32:15 2005 @@ -1,11 +1,11 @@ -from pypy.rpython import objectmodel +from pypy.rpython import rstack def ll_stack_too_big(): - return objectmodel.stack_too_big() + return rstack.stack_too_big() ll_stack_too_big.suggested_primitive = True def ll_stack_unwind(): - objectmodel.stack_unwind() + rstack.stack_unwind() ll_stack_unwind.suggested_primitive = True def ll_stack_check(): Modified: pypy/dist/pypy/rpython/module/ll_stackless.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_stackless.py (original) +++ pypy/dist/pypy/rpython/module/ll_stackless.py Tue Oct 25 13:32:15 2005 @@ -1,5 +1,19 @@ -from pypy.rpython import objectmodel +from pypy.rpython import rstack, lltype, extfunctable +from pypy.rpython.module.support import from_opaque_object, to_opaque_object + +FRAMETOPTYPE = extfunctable.frametop_type_info.get_lltype() + def ll_stackless_stack_frames_depth(): - return objectmodel.stack_frames_depth() + return rstack.stack_frames_depth() ll_stackless_stack_frames_depth.suggested_primitive = True + + +def ll_stackless_switch(opaqueframetop): + frametop = from_opaque_object(opaqueframetop) + newframetop = frametop.switch() + if newframetop is None: + return lltype.nullptr(FRAMETOPTYPE) + else: + return to_opaque_object(newframetop) +ll_stackless_switch.suggested_primitive = True Modified: pypy/dist/pypy/rpython/objectmodel.py ============================================================================== --- pypy/dist/pypy/rpython/objectmodel.py (original) +++ pypy/dist/pypy/rpython/objectmodel.py Tue Oct 25 13:32:15 2005 @@ -3,7 +3,7 @@ RPython-compliant way. """ -import new, inspect +import new def instantiate(cls): @@ -38,22 +38,6 @@ def hlinvoke(repr, llcallable, *args): raise TypeError, "hlinvoke is meant to be rtyped and not called direclty" -def stack_unwind(): - pass - -def stack_frames_depth(): - return len(inspect.stack()) - -def stack_too_big(): - return False - -def stack_check(): - if stack_too_big(): - # stack_unwind implementation is different depending on if stackless - # is enabled. If it is it unwinds the stack, otherwise it simply - # raises a RuntimeError. - stack_unwind() - # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Tue Oct 25 13:32:15 2005 @@ -1,7 +1,7 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython import lltype -from pypy.rpython import rarithmetic, objectmodel +from pypy.rpython import rarithmetic, objectmodel, rstack from pypy.rpython.rtyper import TyperError from pypy.rpython.rrange import rtype_builtin_range, rtype_builtin_xrange from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, Constant @@ -189,6 +189,10 @@ def rtype_we_are_translated(hop): return hop.inputconst(lltype.Bool, True) +def rtype_yield_current_frame_to_caller(hop): + return hop.genop('yield_current_frame_to_caller', [], + resulttype=hop.r_result) + def rtype_hlinvoke(hop): _, s_repr = hop.r_s_popfirstarg() r_callable = s_repr.const @@ -275,6 +279,8 @@ BUILTIN_TYPER[rarithmetic.r_uint] = rtype_r_uint BUILTIN_TYPER[objectmodel.r_dict] = rtype_r_dict BUILTIN_TYPER[objectmodel.we_are_translated] = rtype_we_are_translated +BUILTIN_TYPER[rstack.yield_current_frame_to_caller] = ( + rtype_yield_current_frame_to_caller) BUILTIN_TYPER[objectmodel.hlinvoke] = rtype_hlinvoke Modified: pypy/dist/pypy/rpython/rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/rspecialcase.py (original) +++ pypy/dist/pypy/rpython/rspecialcase.py Tue Oct 25 13:32:15 2005 @@ -44,3 +44,7 @@ def rtype_override_to_opaque_object(hop, clsdef): return hop.genop('to_opaque_object_should_never_be_seen_by_the_backend', [], resulttype=hop.r_result) + +def rtype_override_yield_current_frame_to_caller(hop, clsdef): + return hop.genop('yield_current_frame_to_caller', [], + resulttype=hop.r_result) Added: pypy/dist/pypy/rpython/rstack.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/rpython/rstack.py Tue Oct 25 13:32:15 2005 @@ -0,0 +1,31 @@ +""" +This file defines utilities for manipulating the stack in an +RPython-compliant way, intended mostly for use by the Stackless PyPy. +""" + +import inspect + +def stack_unwind(): + pass + +def stack_frames_depth(): + return len(inspect.stack()) + +def stack_too_big(): + return False + +def stack_check(): + if stack_too_big(): + # stack_unwind implementation is different depending on if stackless + # is enabled. If it is it unwinds the stack, otherwise it simply + # raises a RuntimeError. + stack_unwind() + +# ____________________________________________________________ + +def yield_current_frame_to_caller(): + raise NotImplementedError("only works in translated versions") + +class frame_stack_top(object): + def switch(self): + raise NotImplementedError("only works in translated versions") Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Oct 25 13:32:15 2005 @@ -54,6 +54,7 @@ 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', + ll_stackless.ll_stackless_switch: 'LL_stackless_switch', ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', ll_stack.ll_stack_unwind: 'LL_stack_unwind', ll_stack.ll_stack_too_big: 'LL_stack_too_big', Modified: pypy/dist/pypy/translator/c/src/ll_stackless.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll_stackless.h (original) +++ pypy/dist/pypy/translator/c/src/ll_stackless.h Tue Oct 25 13:32:15 2005 @@ -13,6 +13,11 @@ int state; } slp_frame_t; +typedef struct { + slp_frame_t header; + void* p0; +} slp_frame_1ptr_t; + struct slp_state_decoding_entry_s { void *function; int signature; @@ -33,6 +38,9 @@ long LL_stackless_stack_frames_depth(void); void slp_main_loop(void); char LL_stackless_stack_too_big(void); +struct RPyOpaque_frame_stack_top *slp_return_current_frame_to_caller(void); +struct RPyOpaque_frame_stack_top * +LL_stackless_switch(struct RPyOpaque_frame_stack_top *c); #ifndef PYPY_NOT_MAIN_FILE @@ -67,6 +75,51 @@ slp_frame_stack_top = NULL; } +struct RPyOpaque_frame_stack_top *slp_return_current_frame_to_caller(void) +{ + slp_frame_t *result = slp_frame_stack_top; + assert(slp_frame_stack_top != NULL); + assert(slp_frame_stack_bottom != NULL); + slp_frame_stack_bottom->f_back = slp_new_frame(sizeof(slp_frame_t), 3); + slp_frame_stack_top = slp_frame_stack_bottom = NULL; /* stop unwinding */ + return (struct RPyOpaque_frame_stack_top *) result; +} + +struct RPyOpaque_frame_stack_top *slp_end_of_yielding_function(void) +{ + assert(slp_frame_stack_top != NULL); /* can only be resumed from + slp_return_current_frame_to_caller() */ + assert(slp_retval_voidptr != NULL); + slp_frame_stack_top = (slp_frame_t *) slp_retval_voidptr; + return NULL; +} + +struct RPyOpaque_frame_stack_top * +LL_stackless_switch(struct RPyOpaque_frame_stack_top *c) +{ + slp_frame_t *f; + slp_frame_t *result; + if (slp_frame_stack_top) + goto resume; + + /* first, unwind the current stack */ + f = slp_new_frame(sizeof(slp_frame_1ptr_t), 2); + ((slp_frame_1ptr_t *) f)->p0 = c; + slp_frame_stack_top = slp_frame_stack_bottom = f; + return NULL; + + resume: + /* ready to do the switch. The current (old) frame_stack_top is + f->f_back, which we store where it will be found immediately + after the switch */ + f = slp_frame_stack_top; + result = f->f_back; + + /* grab the saved value of 'c' and do the switch */ + slp_frame_stack_top = (slp_frame_t *) (((slp_frame_1ptr_t *) f)->p0); + return (struct RPyOpaque_frame_stack_top *) result; +} + /* example function for testing */ @@ -131,15 +184,20 @@ } free(pending); /* consumed by the previous call */ - if (slp_frame_stack_bottom) + if (slp_frame_stack_top) break; if (!back) return; pending = back; slp_frame_stack_top = pending; } - assert(slp_frame_stack_bottom->f_back == NULL); - slp_frame_stack_bottom->f_back = back; + /* slp_frame_stack_bottom is usually non-NULL here, apart from + when returning from switch() */ + if (slp_frame_stack_bottom != NULL) + { + assert(slp_frame_stack_bottom->f_back == NULL); + slp_frame_stack_bottom->f_back = back; + } } } Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 25 13:32:15 2005 @@ -26,6 +26,12 @@ self.registerunwindable('LL_stackless_stack_frames_depth', lltype.FuncType([], lltype.Signed), resume_points=1) + self.registerunwindable('LL_stackless_switch', + lltype.FuncType([Address], Address), + resume_points=1) + self.registerunwindable('slp_end_of_yielding_function', + lltype.FuncType([], Address), + resume_points=1) def registerunwindable(self, functionname, FUNC, resume_points): if resume_points >= 1: @@ -181,7 +187,7 @@ del self.savelines del self.resumeblocks - def check_directcall_result(self, op, err): + def check_directcall_result(self, op, err, specialreturnvalue=None): stacklessdata = self.db.stacklessdata block = self.currentblock curpos = block.operations.index(op) @@ -216,7 +222,8 @@ arguments = ['%d' % globalstatecounter] + vars savecall = 'save_%s(%s);' % (structname, ', '.join(arguments)) - savecall += ' return %s;' % self.error_return_value() + returnvalue = specialreturnvalue or self.error_return_value() + savecall += ' return %s;' % returnvalue self.savelines.append('%s: %s' % (savelabel, savecall)) # generate the resume block, e.g. @@ -250,6 +257,17 @@ resumelabel, exception_check) + def OP_YIELD_CURRENT_FRAME_TO_CALLER(self, op, err): + # special handling of this operation: call stack_unwind() to force the + # current frame to be saved into the heap, but don't propagate the + # unwind -- instead, capture it and return it normally + line = '/* yield_current_frame_to_caller */\n' + line += '%s = NULL;\n' % self.expr(op.result) + line += 'LL_stackless_stack_unwind();\n' + line += self.check_directcall_result(op, err, + specialreturnvalue='slp_return_current_frame_to_caller()') + return line + def signature_type(T): """Return T unless it's a pointer type, in which case we return a general Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Tue Oct 25 13:32:15 2005 @@ -2,7 +2,6 @@ from pypy.translator.tool.cbuild import build_executable from pypy.annotation.model import SomeList, SomeString from pypy.annotation.listdef import ListDef -from pypy.rpython.objectmodel import stack_unwind, stack_frames_depth, stack_too_big import os @@ -24,135 +23,3 @@ cbuilder.compile() data = cbuilder.cmdexec('hi there') assert data.startswith('''hello world\nargument count: 2\n 'hi'\n 'there'\n''') - - -def test_stack_depth(): - def g1(): - "just to check Void special cases around the code" - def g2(ignored): - g1() - def f(n): - g1() - if n > 0: - res = f(n-1) - else: - res = stack_frames_depth() - g2(g1) - return res - - def fn(): - count0 = f(0) - count10 = f(10) - return count10 - count0 - - data = wrap_stackless_function(fn) - assert data.strip() == '10' - -def test_stack_withptr(): - def f(n): - if n > 0: - res = f(n-1) - else: - res = stack_frames_depth(), 1 - return res - - def fn(): - count0, _ = f(0) - count10, _ = f(10) - return count10 - count0 - - data = wrap_stackless_function(fn) - assert data.strip() == '10' - -def test_stackless_manytimes(): - def f(n): - if n > 0: - stack_frames_depth() - res = f(n-1) - else: - res = stack_frames_depth(), 1 - return res - - def fn(): - count0, _ = f(0) - count10, _ = f(100) - return count10 - count0 - - data = wrap_stackless_function(fn) - assert data.strip() == '100' - -def test_stackless_arguments(): - def f(n, d, t): - if n > 0: - res = f(n-1, d, t) - else: - res = stack_frames_depth(), d, t - return res - - def fn(): - count0, d, t = f(0, 5.5, (1, 2)) - count10, d, t = f(10, 5.5, (1, 2)) - return "[" + str(count10 - count0) + ", " + str(d) + ", " + str(t[0]) + ", " + str(t[1]) + "]" - - data = wrap_stackless_function(fn) - assert eval(data) == [10, 5.5, 1, 2] - - -def test_stack_too_big(): - def f1(): - return stack_too_big() - def f2(): - return lst[1]() - def f3(): - return lst[2]() - def f4(): - return lst[3]() - def f5(): - return lst[4]() - lst = [None,f1,f2,f3,f4,f5] - - def f(n): - if lst[5](): - return n - return f(n)+1 - - def fn(): - return f(0) - data = wrap_stackless_function(fn) - assert int(data.strip()) > 500 - - - -def wrap_stackless_function(fn): - def entry_point(argv): - os.write(1, str(fn())+"\n") - return 0 - - t = Translator(entry_point) - s_list_of_strings = SomeList(ListDef(None, SomeString())) - ann = t.annotate([s_list_of_strings]) - t.specialize() - cbuilder = t.cbuilder(standalone=True) - cbuilder.stackless = True - cbuilder.generate_source() - cbuilder.compile() - return cbuilder.cmdexec('') - -def test_stack_unwind(): - def f(): - stack_unwind() - return 42 - - data = wrap_stackless_function(f) - assert int(data.strip()) == 42 - -def test_auto_stack_unwind(): - def f(n): - if n == 1: - return 1 - return (n+f(n-1)) % 1291 - - def fn(): - return f(10**6) - data = wrap_stackless_function(fn) - assert int(data.strip()) == 704 Modified: pypy/dist/pypy/translator/transform.py ============================================================================== --- pypy/dist/pypy/translator/transform.py (original) +++ pypy/dist/pypy/translator/transform.py Tue Oct 25 13:32:15 2005 @@ -14,7 +14,7 @@ from pypy.translator.annrpython import CannotSimplify from pypy.annotation import model as annmodel from pypy.annotation.specialize import MemoTable -from pypy.rpython.objectmodel import stack_check +from pypy.rpython.rstack import stack_check def checkgraphs(self, blocks): seen = {} From pedronis at codespeak.net Tue Oct 25 13:50:47 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 25 Oct 2005 13:50:47 +0200 (CEST) Subject: [pypy-svn] r18929 - pypy/dist/pypy/doc Message-ID: <20051025115047.39BE727B69@code1.codespeak.net> Author: pedronis Date: Tue Oct 25 13:50:46 2005 New Revision: 18929 Added: pypy/dist/pypy/doc/getting-started-0.8.txt - copied, changed from r18926, pypy/dist/pypy/doc/getting-started.txt Log: start of an updated getting-started based on the new translate_pypy and mentioning translatable thunk. From pedronis at codespeak.net Tue Oct 25 14:21:16 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 25 Oct 2005 14:21:16 +0200 (CEST) Subject: [pypy-svn] r18931 - pypy/dist/pypy/doc Message-ID: <20051025122116.D8C0F27B76@code1.codespeak.net> Author: pedronis Date: Tue Oct 25 14:21:16 2005 New Revision: 18931 Modified: pypy/dist/pypy/doc/getting-started-0.8.txt Log: missing word Modified: pypy/dist/pypy/doc/getting-started-0.8.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started-0.8.txt (original) +++ pypy/dist/pypy/doc/getting-started-0.8.txt Tue Oct 25 14:21:16 2005 @@ -482,7 +482,7 @@ * ``--gc=boehm|ref``: choose between using the `Boehm-Demers-Weiser garbage collector`_ or our own reference counting implementation - (as we seen Boehm's collector is the default). + (as we have seen Boehm's collector is the default). .. XXX: --stackless ? it's own section? From pedronis at codespeak.net Tue Oct 25 14:27:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 25 Oct 2005 14:27:28 +0200 (CEST) Subject: [pypy-svn] r18932 - pypy/dist/pypy/doc Message-ID: <20051025122728.26E9827B76@code1.codespeak.net> Author: pedronis Date: Tue Oct 25 14:27:27 2005 New Revision: 18932 Modified: pypy/dist/pypy/doc/getting-started-0.8.txt Log: updated session example Modified: pypy/dist/pypy/doc/getting-started-0.8.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started-0.8.txt (original) +++ pypy/dist/pypy/doc/getting-started-0.8.txt Tue Oct 25 14:27:27 2005 @@ -446,12 +446,13 @@ (because of ``--run`` option) by the friendly prompt of a PyPy executable that is not running on top of CPython any more:: - Running! + [translation:info] created: ./pypy-c + [translation:info] Running compiled c source... debug: entry point starting debug: argv -> ./pypy-c - importing code - calling code.interact() - Python 2.4.1 (pypy 0.7.0 build) on linux2 + debug: importing code + debug: calling code.interact() + Python 2.4.1 (pypy 0.7.1 build 18929) on linux2 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>>> 1 + 1 From afa at codespeak.net Tue Oct 25 15:11:28 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 25 Oct 2005 15:11:28 +0200 (CEST) Subject: [pypy-svn] r18933 - pypy/dist/pypy/translator/c/src Message-ID: <20051025131128.D847A27B76@code1.codespeak.net> Author: afa Date: Tue Oct 25 15:11:26 2005 New Revision: 18933 Added: pypy/dist/pypy/translator/c/src/addrinfo.h pypy/dist/pypy/translator/c/src/getaddrinfo.c pypy/dist/pypy/translator/c/src/getnameinfo.c Modified: pypy/dist/pypy/translator/c/src/ll__socket.h Log: Let the socket module compile with Msvc6: this compiler doesn't declare getaddrinfo. Added 3 big files stolen from CPython. This assumes that PyConfig.h is correct, and needs more tests on other platforms. Added: pypy/dist/pypy/translator/c/src/addrinfo.h ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/addrinfo.h Tue Oct 25 15:11:26 2005 @@ -0,0 +1,177 @@ +/* Copied from python 2.4.1: Modules/addrinfo.h */ +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HAVE_GETADDRINFO + +/* + * Error return codes from getaddrinfo() + */ +#ifdef EAI_ADDRFAMILY +/* If this is defined, there is a conflicting implementation + in the C library, which can't be used for some reason. + Make sure it won't interfere with this emulation. */ + +#undef EAI_ADDRFAMILY +#undef EAI_AGAIN +#undef EAI_BADFLAGS +#undef EAI_FAIL +#undef EAI_FAMILY +#undef EAI_MEMORY +#undef EAI_NODATA +#undef EAI_NONAME +#undef EAI_SERVICE +#undef EAI_SOCKTYPE +#undef EAI_SYSTEM +#undef EAI_BADHINTS +#undef EAI_PROTOCOL +#undef EAI_MAX +#undef getaddrinfo +#define getaddrinfo fake_getaddrinfo +#endif /* EAI_ADDRFAMILY */ + +#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with hostname */ +#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ +#define EAI_BADHINTS 12 +#define EAI_PROTOCOL 13 +#define EAI_MAX 14 + +/* + * Flag values for getaddrinfo() + */ +#ifdef AI_PASSIVE +#undef AI_PASSIVE +#undef AI_CANONNAME +#undef AI_NUMERICHOST +#undef AI_MASK +#undef AI_ALL +#undef AI_V4MAPPED_CFG +#undef AI_ADDRCONFIG +#undef AI_V4MAPPED +#undef AI_DEFAULT +#endif /* AI_PASSIVE */ + +#define AI_PASSIVE 0x00000001 /* get address to use bind() */ +#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ +#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ +/* valid flags for addrinfo */ +#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) + +#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ +#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ +#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ +#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ +/* special recommended flags for getipnodebyname */ +#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) + +#endif /* !HAVE_GETADDRINFO */ + +#ifndef HAVE_GETNAMEINFO + +/* + * Constants for getnameinfo() + */ +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 +#endif /* !NI_MAXHOST */ + +/* + * Flag values for getnameinfo() + */ +#ifndef NI_NOFQDN +#define NI_NOFQDN 0x00000001 +#define NI_NUMERICHOST 0x00000002 +#define NI_NAMEREQD 0x00000004 +#define NI_NUMERICSERV 0x00000008 +#define NI_DGRAM 0x00000010 +#endif /* !NI_NOFQDN */ + +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef HAVE_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_ADDRINFO */ + +#ifndef HAVE_SOCKADDR_STORAGE +/* + * RFC 2553: protocol-independent placeholder for socket addresses + */ +#define _SS_MAXSIZE 128 +#ifdef HAVE_LONG_LONG +#define _SS_ALIGNSIZE (sizeof(PY_LONG_LONG)) +#else +#define _SS_ALIGNSIZE (sizeof(double)) +#endif /* HAVE_LONG_LONG */ +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) +#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ + _SS_PAD1SIZE - _SS_ALIGNSIZE) + +struct sockaddr_storage { +#ifdef HAVE_SOCKADDR_SA_LEN + unsigned char ss_len; /* address length */ + unsigned char ss_family; /* address family */ +#else + unsigned short ss_family; /* address family */ +#endif /* HAVE_SOCKADDR_SA_LEN */ + char __ss_pad1[_SS_PAD1SIZE]; +#ifdef HAVE_LONG_LONG + PY_LONG_LONG __ss_align; /* force desired structure storage alignment */ +#else + double __ss_align; /* force desired structure storage alignment */ +#endif /* HAVE_LONG_LONG */ + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif /* !HAVE_SOCKADDR_STORAGE */ + +#ifdef __cplusplus +extern "C" { +#endif +extern void freehostent Py_PROTO((struct hostent *)); +#ifdef __cplusplus +} +#endif Added: pypy/dist/pypy/translator/c/src/getaddrinfo.c ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/getaddrinfo.c Tue Oct 25 15:11:26 2005 @@ -0,0 +1,639 @@ +/* Copied from python 2.4.1: Modules/getaddrinfo.c */ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * GAI_ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR GAI_ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON GAI_ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN GAI_ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * "#ifdef FAITH" part is local hack for supporting IPv4-v6 translator. + * + * Issues to be discussed: + * - Thread safe-ness must be checked. + * - Return values. There are nonstandard return values defined and used + * in the source code. This is because RFC2133 is silent about which error + * code must be returned for which situation. + * - PF_UNSPEC case would be handled in getipnodebyname() with the AI_ALL flag. + */ + +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "addrinfo.h" +#endif + +#if defined(__KAME__) && defined(ENABLE_IPV6) +# define FAITH +#endif + +#define SUCCESS 0 +#define GAI_ANY 0 +#define YES 1 +#define NO 0 + +#ifdef FAITH +static int translate = NO; +static struct in6_addr faith_prefix = IN6ADDR_GAI_ANY_INIT; +#endif + +static const char in_addrany[] = { 0, 0, 0, 0 }; +static const char in6_addrany[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; +static const char in_loopback[] = { 127, 0, 0, 1 }; +static const char in6_loopback[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 +}; + +struct sockinet { + u_char si_len; + u_char si_family; + u_short si_port; +}; + +static struct gai_afd { + int a_af; + int a_addrlen; + int a_socklen; + int a_off; + const char *a_addrany; + const char *a_loopback; +} gai_afdl [] = { +#ifdef ENABLE_IPV6 +#define N_INET6 0 + {PF_INET6, sizeof(struct in6_addr), + sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr), + in6_addrany, in6_loopback}, +#define N_INET 1 +#else +#define N_INET 0 +#endif + {PF_INET, sizeof(struct in_addr), + sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr), + in_addrany, in_loopback}, + {0, 0, 0, 0, NULL, NULL}, +}; + +#ifdef ENABLE_IPV6 +#define PTON_MAX 16 +#else +#define PTON_MAX 4 +#endif + +#ifndef IN_MULTICAST +#define IN_MULTICAST(i) (((i) & 0xf0000000U) == 0xe0000000U) +#endif + +#ifndef IN_EXPERIMENTAL +#define IN_EXPERIMENTAL(i) (((i) & 0xe0000000U) == 0xe0000000U) +#endif + +#ifndef IN_LOOPBACKNET +#define IN_LOOPBACKNET 127 +#endif + +static int get_name Py_PROTO((const char *, struct gai_afd *, + struct addrinfo **, char *, struct addrinfo *, + int)); +static int get_addr Py_PROTO((const char *, int, struct addrinfo **, + struct addrinfo *, int)); +static int str_isnumber Py_PROTO((const char *)); + +static char *ai_errlist[] = { + "success.", + "address family for hostname not supported.", /* EAI_ADDRFAMILY */ + "temporary failure in name resolution.", /* EAI_AGAIN */ + "invalid value for ai_flags.", /* EAI_BADFLAGS */ + "non-recoverable failure in name resolution.", /* EAI_FAIL */ + "ai_family not supported.", /* EAI_FAMILY */ + "memory allocation failure.", /* EAI_MEMORY */ + "no address associated with hostname.", /* EAI_NODATA */ + "hostname nor servname provided, or not known.",/* EAI_NONAME */ + "servname not supported for ai_socktype.", /* EAI_SERVICE */ + "ai_socktype not supported.", /* EAI_SOCKTYPE */ + "system error returned in errno.", /* EAI_SYSTEM */ + "invalid value for hints.", /* EAI_BADHINTS */ + "resolved protocol is unknown.", /* EAI_PROTOCOL */ + "unknown error.", /* EAI_MAX */ +}; + +#define GET_CANONNAME(ai, str) \ +if (pai->ai_flags & AI_CANONNAME) {\ + if (((ai)->ai_canonname = (char *)malloc(strlen(str) + 1)) != NULL) {\ + strcpy((ai)->ai_canonname, (str));\ + } else {\ + error = EAI_MEMORY;\ + goto free;\ + }\ +} + +#ifdef HAVE_SOCKADDR_SA_LEN +#define GET_AI(ai, gai_afd, addr, port) {\ + char *p;\ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ + ((gai_afd)->a_socklen)))\ + == NULL) goto free;\ + memcpy(ai, pai, sizeof(struct addrinfo));\ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ + memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ + (ai)->ai_addr->sa_len = (ai)->ai_addrlen = (gai_afd)->a_socklen;\ + (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ + ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ + p = (char *)((ai)->ai_addr);\ + memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ +} +#else +#define GET_AI(ai, gai_afd, addr, port) {\ + char *p;\ + if (((ai) = (struct addrinfo *)malloc(sizeof(struct addrinfo) +\ + ((gai_afd)->a_socklen)))\ + == NULL) goto free;\ + memcpy(ai, pai, sizeof(struct addrinfo));\ + (ai)->ai_addr = (struct sockaddr *)((ai) + 1);\ + memset((ai)->ai_addr, 0, (gai_afd)->a_socklen);\ + (ai)->ai_addrlen = (gai_afd)->a_socklen;\ + (ai)->ai_addr->sa_family = (ai)->ai_family = (gai_afd)->a_af;\ + ((struct sockinet *)(ai)->ai_addr)->si_port = port;\ + p = (char *)((ai)->ai_addr);\ + memcpy(p + (gai_afd)->a_off, (addr), (gai_afd)->a_addrlen);\ +} +#endif + +#define ERR(err) { error = (err); goto bad; } + +char * +gai_strerror(int ecode) +{ + if (ecode < 0 || ecode > EAI_MAX) + ecode = EAI_MAX; + return ai_errlist[ecode]; +} + +void +freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + do { + next = ai->ai_next; + if (ai->ai_canonname) + free(ai->ai_canonname); + /* no need to free(ai->ai_addr) */ + free(ai); + } while ((ai = next) != NULL); +} + +static int +str_isnumber(const char *p) +{ + unsigned char *q = (unsigned char *)p; + while (*q) { + if (! isdigit(*q)) + return NO; + q++; + } + return YES; +} + +int +getaddrinfo(const char*hostname, const char*servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct addrinfo sentinel; + struct addrinfo *top = NULL; + struct addrinfo *cur; + int i, error = 0; + char pton[PTON_MAX]; + struct addrinfo ai; + struct addrinfo *pai; + u_short port; + +#ifdef FAITH + static int firsttime = 1; + + if (firsttime) { + /* translator hack */ + { + char *q = getenv("GAI"); + if (q && inet_pton(AF_INET6, q, &faith_prefix) == 1) + translate = YES; + } + firsttime = 0; + } +#endif + + /* initialize file static vars */ + sentinel.ai_next = NULL; + cur = &sentinel; + pai = &ai; + pai->ai_flags = 0; + pai->ai_family = PF_UNSPEC; + pai->ai_socktype = GAI_ANY; + pai->ai_protocol = GAI_ANY; + pai->ai_addrlen = 0; + pai->ai_canonname = NULL; + pai->ai_addr = NULL; + pai->ai_next = NULL; + port = GAI_ANY; + + if (hostname == NULL && servname == NULL) + return EAI_NONAME; + if (hints) { + /* error check for hints */ + if (hints->ai_addrlen || hints->ai_canonname || + hints->ai_addr || hints->ai_next) + ERR(EAI_BADHINTS); /* xxx */ + if (hints->ai_flags & ~AI_MASK) + ERR(EAI_BADFLAGS); + switch (hints->ai_family) { + case PF_UNSPEC: + case PF_INET: +#ifdef ENABLE_IPV6 + case PF_INET6: +#endif + break; + default: + ERR(EAI_FAMILY); + } + memcpy(pai, hints, sizeof(*pai)); + switch (pai->ai_socktype) { + case GAI_ANY: + switch (pai->ai_protocol) { + case GAI_ANY: + break; + case IPPROTO_UDP: + pai->ai_socktype = SOCK_DGRAM; + break; + case IPPROTO_TCP: + pai->ai_socktype = SOCK_STREAM; + break; + default: + pai->ai_socktype = SOCK_RAW; + break; + } + break; + case SOCK_RAW: + break; + case SOCK_DGRAM: + if (pai->ai_protocol != IPPROTO_UDP && + pai->ai_protocol != GAI_ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_UDP; + break; + case SOCK_STREAM: + if (pai->ai_protocol != IPPROTO_TCP && + pai->ai_protocol != GAI_ANY) + ERR(EAI_BADHINTS); /*xxx*/ + pai->ai_protocol = IPPROTO_TCP; + break; + default: + ERR(EAI_SOCKTYPE); + /* unreachable */ + } + } + + /* + * service port + */ + if (servname) { + if (str_isnumber(servname)) { + if (pai->ai_socktype == GAI_ANY) { + /* caller accept *GAI_ANY* socktype */ + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } + port = htons((u_short)atoi(servname)); + } else { + struct servent *sp; + char *proto; + + proto = NULL; + switch (pai->ai_socktype) { + case GAI_ANY: + proto = NULL; + break; + case SOCK_DGRAM: + proto = "udp"; + break; + case SOCK_STREAM: + proto = "tcp"; + break; + default: + fprintf(stderr, "panic!\n"); + break; + } + if ((sp = getservbyname(servname, proto)) == NULL) + ERR(EAI_SERVICE); + port = sp->s_port; + if (pai->ai_socktype == GAI_ANY) { + if (strcmp(sp->s_proto, "udp") == 0) { + pai->ai_socktype = SOCK_DGRAM; + pai->ai_protocol = IPPROTO_UDP; + } else if (strcmp(sp->s_proto, "tcp") == 0) { + pai->ai_socktype = SOCK_STREAM; + pai->ai_protocol = IPPROTO_TCP; + } else + ERR(EAI_PROTOCOL); /*xxx*/ + } + } + } + + /* + * hostname == NULL. + * passive socket -> anyaddr (0.0.0.0 or ::) + * non-passive socket -> localhost (127.0.0.1 or ::1) + */ + if (hostname == NULL) { + struct gai_afd *gai_afd; + + for (gai_afd = &gai_afdl[0]; gai_afd->a_af; gai_afd++) { + if (!(pai->ai_family == PF_UNSPEC + || pai->ai_family == gai_afd->a_af)) { + continue; + } + + if (pai->ai_flags & AI_PASSIVE) { + GET_AI(cur->ai_next, gai_afd, gai_afd->a_addrany, port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "anyaddr"); + */ + } else { + GET_AI(cur->ai_next, gai_afd, gai_afd->a_loopback, + port); + /* xxx meaningless? + * GET_CANONNAME(cur->ai_next, "localhost"); + */ + } + cur = cur->ai_next; + } + top = sentinel.ai_next; + if (top) + goto good; + else + ERR(EAI_FAMILY); + } + + /* hostname as numeric name */ + for (i = 0; gai_afdl[i].a_af; i++) { + if (inet_pton(gai_afdl[i].a_af, hostname, pton)) { + u_long v4a; +#ifdef ENABLE_IPV6 + u_char pfx; +#endif + + switch (gai_afdl[i].a_af) { + case AF_INET: + v4a = ((struct in_addr *)pton)->s_addr; + v4a = ntohl(v4a); + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + pai->ai_flags &= ~AI_CANONNAME; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0 || v4a == IN_LOOPBACKNET) + pai->ai_flags &= ~AI_CANONNAME; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + pfx = ((struct in6_addr *)pton)->s6_addr8[0]; + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + pai->ai_flags &= ~AI_CANONNAME; + break; +#endif + } + + if (pai->ai_family == gai_afdl[i].a_af || + pai->ai_family == PF_UNSPEC) { + if (! (pai->ai_flags & AI_CANONNAME)) { + GET_AI(top, &gai_afdl[i], pton, port); + goto good; + } + /* + * if AI_CANONNAME and if reverse lookup + * fail, return ai anyway to pacify + * calling application. + * + * XXX getaddrinfo() is a name->address + * translation function, and it looks strange + * that we do addr->name translation here. + */ + get_name(pton, &gai_afdl[i], &top, pton, pai, port); + goto good; + } else + ERR(EAI_FAMILY); /*xxx*/ + } + } + + if (pai->ai_flags & AI_NUMERICHOST) + ERR(EAI_NONAME); + + /* hostname as alphabetical name */ + error = get_addr(hostname, pai->ai_family, &top, pai, port); + if (error == 0) { + if (top) { + good: + *res = top; + return SUCCESS; + } else + error = EAI_FAIL; + } + free: + if (top) + freeaddrinfo(top); + bad: + *res = NULL; + return error; +} + +static int +get_name(addr, gai_afd, res, numaddr, pai, port0) + const char *addr; + struct gai_afd *gai_afd; + struct addrinfo **res; + char *numaddr; + struct addrinfo *pai; + int port0; +{ + u_short port = port0 & 0xffff; + struct hostent *hp; + struct addrinfo *cur; + int error = 0; +#ifdef ENABLE_IPV6 + int h_error; +#endif + +#ifdef ENABLE_IPV6 + hp = getipnodebyaddr(addr, gai_afd->a_addrlen, gai_afd->a_af, &h_error); +#else + hp = gethostbyaddr(addr, gai_afd->a_addrlen, AF_INET); +#endif + if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + GET_AI(cur, gai_afd, hp->h_addr_list[0], port); + GET_CANONNAME(cur, hp->h_name); + } else + GET_AI(cur, gai_afd, numaddr, port); + +#ifdef ENABLE_IPV6 + if (hp) + freehostent(hp); +#endif + *res = cur; + return SUCCESS; + free: + if (cur) + freeaddrinfo(cur); +#ifdef ENABLE_IPV6 + if (hp) + freehostent(hp); +#endif + /* bad: */ + *res = NULL; + return error; +} + +static int +get_addr(hostname, af, res, pai, port0) + const char *hostname; + int af; + struct addrinfo **res; + struct addrinfo *pai; + int port0; +{ + u_short port = port0 & 0xffff; + struct addrinfo sentinel; + struct hostent *hp; + struct addrinfo *top, *cur; + struct gai_afd *gai_afd; + int i, error = 0, h_error; + char *ap; + + top = NULL; + sentinel.ai_next = NULL; + cur = &sentinel; +#ifdef ENABLE_IPV6 + if (af == AF_UNSPEC) { + hp = getipnodebyname(hostname, AF_INET6, + AI_ADDRCONFIG|AI_ALL|AI_V4MAPPED, &h_error); + } else + hp = getipnodebyname(hostname, af, AI_ADDRCONFIG, &h_error); +#else + hp = gethostbyname(hostname); + h_error = h_errno; +#endif + if (hp == NULL) { + switch (h_error) { + case HOST_NOT_FOUND: + case NO_DATA: + error = EAI_NODATA; + break; + case TRY_AGAIN: + error = EAI_AGAIN; + break; + case NO_RECOVERY: + default: + error = EAI_FAIL; + break; + } + goto free; + } + + if ((hp->h_name == NULL) || (hp->h_name[0] == 0) || + (hp->h_addr_list[0] == NULL)) { + error = EAI_FAIL; + goto free; + } + + for (i = 0; (ap = hp->h_addr_list[i]) != NULL; i++) { + switch (af) { +#ifdef ENABLE_IPV6 + case AF_INET6: + gai_afd = &gai_afdl[N_INET6]; + break; +#endif +#ifndef ENABLE_IPV6 + default: /* AF_UNSPEC */ +#endif + case AF_INET: + gai_afd = &gai_afdl[N_INET]; + break; +#ifdef ENABLE_IPV6 + default: /* AF_UNSPEC */ + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ap)) { + ap += sizeof(struct in6_addr) - + sizeof(struct in_addr); + gai_afd = &gai_afdl[N_INET]; + } else + gai_afd = &gai_afdl[N_INET6]; + break; +#endif + } +#ifdef FAITH + if (translate && gai_afd->a_af == AF_INET) { + struct in6_addr *in6; + + GET_AI(cur->ai_next, &gai_afdl[N_INET6], ap, port); + in6 = &((struct sockaddr_in6 *)cur->ai_next->ai_addr)->sin6_addr; + memcpy(&in6->s6_addr32[0], &faith_prefix, + sizeof(struct in6_addr) - sizeof(struct in_addr)); + memcpy(&in6->s6_addr32[3], ap, sizeof(struct in_addr)); + } else +#endif /* FAITH */ + GET_AI(cur->ai_next, gai_afd, ap, port); + if (cur == &sentinel) { + top = cur->ai_next; + GET_CANONNAME(top, hp->h_name); + } + cur = cur->ai_next; + } +#ifdef ENABLE_IPV6 + freehostent(hp); +#endif + *res = top; + return SUCCESS; + free: + if (top) + freeaddrinfo(top); +#ifdef ENABLE_IPV6 + if (hp) + freehostent(hp); +#endif +/* bad: */ + *res = NULL; + return error; +} Added: pypy/dist/pypy/translator/c/src/getnameinfo.c ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/c/src/getnameinfo.c Tue Oct 25 15:11:26 2005 @@ -0,0 +1,215 @@ +/* Copied from python 2.4.1: Modules/getnameinfo.c */ +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Issues to be discussed: + * - Thread safe-ness must be checked + * - Return values. There seems to be no standard for return value (RFC2133) + * but INRIA implementation returns EAI_xxx defined for getaddrinfo(). + */ + +#if 0 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "addrinfo.h" +#endif + +#define SUCCESS 0 +#define YES 1 +#define NO 0 + +static struct gni_afd { + int a_af; + int a_addrlen; + int a_socklen; + int a_off; +} gni_afdl [] = { +#ifdef ENABLE_IPV6 + {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6), + offsetof(struct sockaddr_in6, sin6_addr)}, +#endif + {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in), + offsetof(struct sockaddr_in, sin_addr)}, + {0, 0, 0}, +}; + +struct gni_sockinet { + u_char si_len; + u_char si_family; + u_short si_port; +}; + +#define ENI_NOSOCKET 0 +#define ENI_NOSERVNAME 1 +#define ENI_NOHOSTNAME 2 +#define ENI_MEMORY 3 +#define ENI_SYSTEM 4 +#define ENI_FAMILY 5 +#define ENI_SALEN 6 + +/* forward declaration to make gcc happy */ +int getnameinfo Py_PROTO((const struct sockaddr *, size_t, char *, size_t, + char *, size_t, int)); + +int +getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) + const struct sockaddr *sa; + size_t salen; + char *host; + size_t hostlen; + char *serv; + size_t servlen; + int flags; +{ + struct gni_afd *gni_afd; + struct servent *sp; + struct hostent *hp; + u_short port; + int family, len, i; + char *addr, *p; + u_long v4a; +#ifdef ENABLE_IPV6 + u_char pfx; +#endif + int h_error; + char numserv[512]; + char numaddr[512]; + + if (sa == NULL) + return ENI_NOSOCKET; + +#ifdef HAVE_SOCKADDR_SA_LEN + len = sa->sa_len; + if (len != salen) return ENI_SALEN; +#else + len = salen; +#endif + + family = sa->sa_family; + for (i = 0; gni_afdl[i].a_af; i++) + if (gni_afdl[i].a_af == family) { + gni_afd = &gni_afdl[i]; + goto found; + } + return ENI_FAMILY; + + found: + if (len != gni_afd->a_socklen) return ENI_SALEN; + + port = ((struct gni_sockinet *)sa)->si_port; /* network byte order */ + addr = (char *)sa + gni_afd->a_off; + + if (serv == NULL || servlen == 0) { + /* what we should do? */ + } else if (flags & NI_NUMERICSERV) { + sprintf(numserv, "%d", ntohs(port)); + if (strlen(numserv) > servlen) + return ENI_MEMORY; + strcpy(serv, numserv); + } else { + sp = getservbyport(port, (flags & NI_DGRAM) ? "udp" : "tcp"); + if (sp) { + if (strlen(sp->s_name) > servlen) + return ENI_MEMORY; + strcpy(serv, sp->s_name); + } else + return ENI_NOSERVNAME; + } + + switch (sa->sa_family) { + case AF_INET: + v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; + if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) + flags |= NI_NUMERICHOST; + v4a >>= IN_CLASSA_NSHIFT; + if (v4a == 0 || v4a == IN_LOOPBACKNET) + flags |= NI_NUMERICHOST; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr8[0]; + if (pfx == 0 || pfx == 0xfe || pfx == 0xff) + flags |= NI_NUMERICHOST; + break; +#endif + } + if (host == NULL || hostlen == 0) { + /* what should we do? */ + } else if (flags & NI_NUMERICHOST) { + if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_SYSTEM; + if (strlen(numaddr) > hostlen) + return ENI_MEMORY; + strcpy(host, numaddr); + } else { +#ifdef ENABLE_IPV6 + hp = getipnodebyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af, &h_error); +#else + hp = gethostbyaddr(addr, gni_afd->a_addrlen, gni_afd->a_af); + h_error = h_errno; +#endif + + if (hp) { + if (flags & NI_NOFQDN) { + p = strchr(hp->h_name, '.'); + if (p) *p = '\0'; + } + if (strlen(hp->h_name) > hostlen) { +#ifdef ENABLE_IPV6 + freehostent(hp); +#endif + return ENI_MEMORY; + } + strcpy(host, hp->h_name); +#ifdef ENABLE_IPV6 + freehostent(hp); +#endif + } else { + if (flags & NI_NAMEREQD) + return ENI_NOHOSTNAME; + if (inet_ntop(gni_afd->a_af, addr, numaddr, sizeof(numaddr)) + == NULL) + return ENI_NOHOSTNAME; + if (strlen(numaddr) > hostlen) + return ENI_MEMORY; + strcpy(host, numaddr); + } + } + return SUCCESS; +} Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Tue Oct 25 15:11:26 2005 @@ -1,6 +1,6 @@ #ifdef MS_WINDOWS -# pragma comment(lib, "ws2_32.lib") + /* winsock2.h has already been included before windows.h in thread_nt.h */ #else # include # include @@ -19,10 +19,40 @@ RPySOCKET_ADDRINFO *LL__socket_nextaddrinfo(struct RPyOpaque_ADDRINFO *addr); #ifndef PYPY_NOT_MAIN_FILE + #ifdef MS_WINDOWS +# pragma comment(lib, "ws2_32.lib") # include +# if _MSC_VER >= 1300 +# define HAVE_ADDRINFO +# define HAVE_SOCKADDR_STORAGE +# define HAVE_GETADDRINFO +# define HAVE_GETNAMEINFO +# define ENABLE_IPV6 +# endif +#endif + +#include "addrinfo.h" + +#ifndef HAVE_INET_PTON +int inet_pton(int af, const char *src, void *dst); +const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); #endif +/* I know this is a bad practice, but it is the easiest... */ +#if !defined(HAVE_GETADDRINFO) +/* avoid clashes with the C library definition of the symbol. */ +#define getaddrinfo fake_getaddrinfo +#define gai_strerror fake_gai_strerror +#define freeaddrinfo fake_freeaddrinfo +#include "getaddrinfo.c" +#endif +#if !defined(HAVE_GETNAMEINFO) +#define getnameinfo fake_getnameinfo +#include "getnameinfo.c" +#endif + + int LL__socket_ntohs(int htons) { return (int)ntohs((short) htons); @@ -134,4 +164,42 @@ freeaddrinfo(addr->info0); free(addr); } -#endif + +#ifndef HAVE_INET_PTON + +/* Simplistic emulation code for inet_pton that only works for IPv4 */ +/* These are not exposed because they do not set errno properly */ + +int +inet_pton(int af, const char *src, void *dst) +{ + if (af == AF_INET) { + long packed_addr; + packed_addr = inet_addr(src); + if (packed_addr == INADDR_NONE) + return 0; + memcpy(dst, &packed_addr, 4); + return 1; + } + /* Should set errno to EAFNOSUPPORT */ + return -1; +} + +const char * +inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + if (af == AF_INET) { + struct in_addr packed_addr; + if (size < 16) + /* Should set errno to ENOSPC. */ + return NULL; + memcpy(&packed_addr, src, sizeof(packed_addr)); + return strncpy(dst, inet_ntoa(packed_addr), size); + } + /* Should set errno to EAFNOSUPPORT */ + return NULL; +} + +#endif /* !HAVE_INET_PTON */ + +#endif /* PYPY_NOT_MAIN_FILE */ From mwh at codespeak.net Tue Oct 25 16:05:37 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 25 Oct 2005 16:05:37 +0200 (CEST) Subject: [pypy-svn] r18934 - in pypy/dist/pypy: annotation module/thread/rpython rpython rpython/l3interp rpython/lltypesystem rpython/memory rpython/memory/test rpython/module rpython/ootypesystem/test rpython/test translator translator/asm translator/backendopt translator/backendopt/test translator/c translator/c/test translator/js translator/js/test translator/llvm translator/llvm/backendopt translator/llvm/test Message-ID: <20051025140537.59EE827B76@code1.codespeak.net> Author: mwh Date: Tue Oct 25 16:05:11 2005 New Revision: 18934 Removed: pypy/dist/pypy/rpython/lltype.py Modified: pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/annotation/model.py pypy/dist/pypy/module/thread/rpython/ll_thread.py pypy/dist/pypy/rpython/annlowlevel.py pypy/dist/pypy/rpython/extfunctable.py pypy/dist/pypy/rpython/l3interp/model.py pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/lltypesystem/rpbc.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/lladdress.py pypy/dist/pypy/rpython/memory/lltypelayout.py pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/support.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py pypy/dist/pypy/rpython/module/ll_math.py pypy/dist/pypy/rpython/module/ll_os.py pypy/dist/pypy/rpython/module/support.py pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py pypy/dist/pypy/rpython/raddress.py pypy/dist/pypy/rpython/rbool.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/rexternalobj.py pypy/dist/pypy/rpython/rfloat.py pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rmodel.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/rslice.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_exception.py pypy/dist/pypy/rpython/test/test_llann.py pypy/dist/pypy/rpython/test/test_llinterp.py pypy/dist/pypy/rpython/test/test_lltype.py pypy/dist/pypy/rpython/test/test_normalizecalls.py pypy/dist/pypy/rpython/test/test_rbool.py pypy/dist/pypy/rpython/test/test_rbuiltin.py pypy/dist/pypy/rpython/test/test_rclass.py pypy/dist/pypy/rpython/test/test_rdict.py pypy/dist/pypy/rpython/test/test_rexternalobj.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/rpython/test/test_robject.py pypy/dist/pypy/rpython/test/test_rpbc.py pypy/dist/pypy/rpython/test/test_rptr.py pypy/dist/pypy/rpython/test/test_rspecialcase.py pypy/dist/pypy/rpython/test/test_rstr.py pypy/dist/pypy/rpython/test/test_rtuple.py pypy/dist/pypy/rpython/test/test_rtyper.py pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/backendopt/inline.py pypy/dist/pypy/translator/backendopt/malloc.py pypy/dist/pypy/translator/backendopt/propagate.py pypy/dist/pypy/translator/backendopt/removenoops.py pypy/dist/pypy/translator/backendopt/tailrecursion.py pypy/dist/pypy/translator/backendopt/test/test_removenoops.py pypy/dist/pypy/translator/c/database.py 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/gc.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/node.py pypy/dist/pypy/translator/c/primitive.py pypy/dist/pypy/translator/c/pyobj.py pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/support.py pypy/dist/pypy/translator/c/symboltable.py pypy/dist/pypy/translator/c/test/test_database.py pypy/dist/pypy/translator/c/test/test_genc.py pypy/dist/pypy/translator/c/test/test_lltyped.py pypy/dist/pypy/translator/c/wrapper.py pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/node.py pypy/dist/pypy/translator/js/opaquenode.py pypy/dist/pypy/translator/js/opwriter.py pypy/dist/pypy/translator/js/structnode.py pypy/dist/pypy/translator/js/test/test_lltype.py pypy/dist/pypy/translator/llvm/arraynode.py pypy/dist/pypy/translator/llvm/backendopt/exception.py pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py pypy/dist/pypy/translator/llvm/database.py pypy/dist/pypy/translator/llvm/externs2ll.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/opaquenode.py pypy/dist/pypy/translator/llvm/opwriter.py pypy/dist/pypy/translator/llvm/pyxwrapper.py pypy/dist/pypy/translator/llvm/structnode.py pypy/dist/pypy/translator/llvm/test/test_lltype.py pypy/dist/pypy/translator/simplify.py Log: remove rpython/lltype.py (easy!) and fix all the references to it to be to rpython/lltypesystem/lltype.py (tedious!). haven't run ALL the tests yet, will do that on snake. Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Tue Oct 25 16:05:11 2005 @@ -326,7 +326,7 @@ # annotation of low-level types from pypy.annotation.model import SomePtr -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype def malloc(T, n=None): assert n is None or n.knowntype == int Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Tue Oct 25 16:05:11 2005 @@ -456,7 +456,7 @@ def __init__(self, method): self.method = method -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype annotation_to_ll_map = [ 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 Oct 25 16:05:11 2005 @@ -4,7 +4,7 @@ """ import thread -from pypy.rpython.lltype import malloc +from pypy.rpython.lltypesystem.lltype import malloc from pypy.rpython.module.support import init_opaque_object, from_opaque_object from pypy.module.thread.rpython.exttable import locktypeinfo Modified: pypy/dist/pypy/rpython/annlowlevel.py ============================================================================== --- pypy/dist/pypy/rpython/annlowlevel.py (original) +++ pypy/dist/pypy/rpython/annlowlevel.py Tue Oct 25 16:05:11 2005 @@ -6,7 +6,7 @@ from pypy.annotation import model as annmodel from pypy.annotation.specialize import decide_callable from pypy.annotation.policy import AnnotatorPolicy -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython import extfunctable def not_const(s_obj): # xxx move it somewhere else Modified: pypy/dist/pypy/rpython/extfunctable.py ============================================================================== --- pypy/dist/pypy/rpython/extfunctable.py (original) +++ pypy/dist/pypy/rpython/extfunctable.py Tue Oct 25 16:05:11 2005 @@ -49,7 +49,7 @@ def get_lltype(self): if self._TYPE is None: - from pypy.rpython import lltype + from pypy.rpython.lltypesystem import lltype OPAQUE = lltype.OpaqueType(self.tag) OPAQUE._exttypeinfo = self if self.needs_container: Modified: pypy/dist/pypy/rpython/l3interp/model.py ============================================================================== --- pypy/dist/pypy/rpython/l3interp/model.py (original) +++ pypy/dist/pypy/rpython/l3interp/model.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ from pypy.rpython.memory import lladdress from pypy.objspace.flow import model as flowmodel -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype very_low_level_ops = [ #operations with adresses: Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Tue Oct 25 16:05:11 2005 @@ -2,7 +2,7 @@ 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 -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.rmodel import getfunctionptr from pypy.rpython.memory import lladdress from pypy.rpython.objectmodel import free_non_gc_object Modified: pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/exceptiondata.py Tue Oct 25 16:05:11 2005 @@ -1,8 +1,9 @@ from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem import rclass 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.lltypesystem.lltype import \ + Array, malloc, Ptr, PyObject, pyobjectptr, \ + FuncType, functionptr, Signed from pypy.rpython.extfunctable import standardexceptions from pypy.annotation.classdef import FORCE_ATTRIBUTES_INTO_CLASSES Modified: pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rbuiltin.py Tue Oct 25 16:05:11 2005 @@ -1,11 +1,11 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype +from pypy.rpython.lltypesystem import rclass from pypy.rpython import objectmodel from pypy.rpython.rmodel import TyperError, Constant from pypy.rpython.robject import pyobj_repr from pypy.rpython.rbool import bool_repr -from pypy.rpython.lltypesystem import rclass def rtype_builtin_isinstance(hop): if hop.s_result.is_constant(): Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Tue Oct 25 16:05:11 2005 @@ -11,12 +11,13 @@ getclassrepr, getinstancerepr,\ get_type_repr, rtype_new_instance,\ instance_annotation_for_cls -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 -from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo, typeOf -from pypy.rpython.lltype import Array, Char, Void, attachRuntimeTypeInfo -from pypy.rpython.lltype import FuncType, Bool, Signed +from pypy.rpython.lltypesystem.lltype import \ + ForwardReference, GcForwardReference, \ + Ptr, Struct, GcStruct, malloc, \ + cast_pointer, castable, nullptr, \ + RuntimeTypeInfo, getRuntimeTypeInfo, typeOf, \ + Array, Char, Void, attachRuntimeTypeInfo, \ + FuncType, Bool, Signed # # There is one "vtable" per user class, with the following structure: Modified: pypy/dist/pypy/rpython/lltypesystem/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rpbc.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rpbc.py Tue Oct 25 16:05:11 2005 @@ -4,8 +4,9 @@ from pypy.annotation import model as annmodel from pypy.annotation.classdef import isclassdef from pypy.objspace.flow.model import Constant -from pypy.rpython.lltype import typeOf, Void, ForwardReference, Struct, Bool -from pypy.rpython.lltype import Ptr, malloc, nullptr +from pypy.rpython.lltypesystem.lltype import \ + typeOf, Void, ForwardReference, Struct, Bool, \ + Ptr, malloc, nullptr from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning from pypy.rpython import robject from pypy.rpython import rtuple Modified: pypy/dist/pypy/rpython/memory/convertlltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/convertlltype.py (original) +++ pypy/dist/pypy/rpython/memory/convertlltype.py Tue Oct 25 16:05:11 2005 @@ -4,7 +4,7 @@ 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.lltypesystem import lltype from pypy.rpython.rmodel import IntegerRepr Modified: pypy/dist/pypy/rpython/memory/gc.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gc.py (original) +++ pypy/dist/pypy/rpython/memory/gc.py Tue Oct 25 16:05:11 2005 @@ -2,7 +2,7 @@ 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 +from pypy.rpython.lltypesystem import lltype from pypy.rpython.objectmodel import free_non_gc_object import sys Modified: pypy/dist/pypy/rpython/memory/gclltype.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gclltype.py (original) +++ pypy/dist/pypy/rpython/memory/gclltype.py Tue Oct 25 16:05:11 2005 @@ -1,9 +1,10 @@ -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.lltypesystem.lltype import \ + LowLevelType, ContainerType, Struct, GcStruct, \ + Array, GcArray, FuncType, OpaqueType, \ + RuntimeTypeInfo, PyObjectType, PyObject, \ + GC_CONTAINER, \ + Signed, Unsigned, Float, Char, Bool, Void, \ + 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 Modified: pypy/dist/pypy/rpython/memory/gcwrapper.py ============================================================================== --- pypy/dist/pypy/rpython/memory/gcwrapper.py (original) +++ pypy/dist/pypy/rpython/memory/gcwrapper.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.annrpython import RPythonAnnotator -from pypy.rpython import lltype +from pypy.rpython.lltypesystem 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 Modified: pypy/dist/pypy/rpython/memory/lladdress.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lladdress.py (original) +++ pypy/dist/pypy/rpython/memory/lladdress.py Tue Oct 25 16:05:11 2005 @@ -109,7 +109,7 @@ return simulator.get_py_object(address.intaddress) -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype Address = lltype.Primitive("Address", NULL) address._TYPE = Address Modified: pypy/dist/pypy/rpython/memory/lltypelayout.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypelayout.py (original) +++ pypy/dist/pypy/rpython/memory/lltypelayout.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.memory import lladdress import struct Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Tue Oct 25 16:05:11 2005 @@ -4,7 +4,7 @@ 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 +from pypy.rpython.lltypesystem import lltype log = py.log.Producer("lltypesim") Modified: pypy/dist/pypy/rpython/memory/support.py ============================================================================== --- pypy/dist/pypy/rpython/memory/support.py (original) +++ pypy/dist/pypy/rpython/memory/support.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.rpython.memory.lladdress import raw_malloc, raw_free, NULL -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.memory.lltypelayout import sizeof import struct 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 Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import py -from pypy.rpython.lltype import typeOf, Ptr, PyObject +from pypy.rpython.lltypesystem.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 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 Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype import math import py 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 Tue Oct 25 16:05:11 2005 @@ -15,7 +15,8 @@ import os, errno from pypy.rpython.rstr import STR -from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc +from pypy.rpython.lltypesystem.lltype import \ + GcStruct, Signed, Array, Char, Ptr, malloc from pypy.rpython.module.support import to_rstr, from_rstr, ll_strcpy from pypy.rpython.module.support import to_opaque_object, from_opaque_object from pypy.rpython import ros Modified: pypy/dist/pypy/rpython/module/support.py ============================================================================== --- pypy/dist/pypy/rpython/module/support.py (original) +++ pypy/dist/pypy/rpython/module/support.py Tue Oct 25 16:05:11 2005 @@ -1,7 +1,8 @@ -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython import extfunctable from pypy.rpython.rstr import STR -from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc +from pypy.rpython.lltypesystem.lltype import \ + GcStruct, Signed, Array, Char, Ptr, malloc # utility conversion functions Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/test/test_ooclean.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.translator import Translator -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.ootypesystem import ootype from pypy.rpython.test.test_llinterp import get_interpreter import py Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Tue Oct 25 16:05:11 2005 @@ -3,7 +3,7 @@ from pypy.annotation import model as annmodel from pypy.rpython.memory.lladdress import address, NULL, Address from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype class __extend__(annmodel.SomeAddress): def rtyper_makerepr(self, rtyper): Modified: pypy/dist/pypy/rpython/rbool.py ============================================================================== --- pypy/dist/pypy/rpython/rbool.py (original) +++ pypy/dist/pypy/rpython/rbool.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Signed, Unsigned, Bool, Float, pyobjectptr +from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, pyobjectptr from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, BoolRepr from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rmodel import log Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython import rarithmetic, objectmodel, rstack from pypy.rpython.rtyper import TyperError from pypy.rpython.rrange import rtype_builtin_range, rtype_builtin_xrange Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Tue Oct 25 16:05:11 2005 @@ -1,12 +1,13 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython import rmodel, lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.rarithmetic import r_uint from pypy.rpython.objectmodel import hlinvoke from pypy.rpython import rlist from pypy.rpython import robject from pypy.rpython import objectmodel +from pypy.rpython import rmodel # ____________________________________________________________ # Modified: pypy/dist/pypy/rpython/rexternalobj.py ============================================================================== --- pypy/dist/pypy/rpython/rexternalobj.py (original) +++ pypy/dist/pypy/rpython/rexternalobj.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.rmodel import Repr from pypy.rpython.extfunctable import typetable from pypy.rpython import rbuiltin Modified: pypy/dist/pypy/rpython/rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/rfloat.py (original) +++ pypy/dist/pypy/rpython/rfloat.py Tue Oct 25 16:05:11 2005 @@ -1,12 +1,12 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Signed, Unsigned, Bool, Float, Void, Ptr +from pypy.rpython.lltypesystem.lltype import \ + Signed, Unsigned, Bool, Float, Void, Ptr, \ + PyObject, Array, Char, functionptr, FuncType, malloc from pypy.rpython.rmodel import Repr, TyperError, FloatRepr from pypy.rpython.rmodel import IntegerRepr, BoolRepr from pypy.rpython.robject import PyObjRepr, pyobj_repr -from pypy.rpython.lltype import PyObject, Array, Char from pypy.rpython.rstr import STR, string_repr -from pypy.rpython.lltype import functionptr, FuncType, malloc from pypy.rpython import rstr from pypy.rpython.rmodel import log Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Tue Oct 25 16:05:11 2005 @@ -2,8 +2,8 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.objspace import op_appendices -from pypy.rpython.lltype import Signed, Unsigned, Bool, Float, Void, Char, \ - UniChar, GcArray, malloc, Array, pyobjectptr +from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \ + Void, Char, UniChar, GcArray, malloc, Array, pyobjectptr from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, CharRepr, \ inputconst from pypy.rpython.robject import PyObjRepr, pyobj_repr Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Tue Oct 25 16:05:11 2005 @@ -6,9 +6,10 @@ from pypy.rpython.rslice import SliceRepr from pypy.rpython.rslice import startstop_slice_repr, startonly_slice_repr from pypy.rpython.rslice import minusone_slice_repr -from pypy.rpython.lltype import GcForwardReference, Ptr, GcArray, GcStruct -from pypy.rpython.lltype import Void, Signed, malloc, typeOf, Primitive -from pypy.rpython.lltype import Bool, nullptr, typeMethod +from pypy.rpython.lltypesystem. lltype import \ + GcForwardReference, Ptr, GcArray, GcStruct, \ + Void, Signed, malloc, typeOf, Primitive, \ + Bool, nullptr, typeMethod from pypy.rpython import rstr from pypy.rpython import robject Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Tue Oct 25 16:05:11 2005 @@ -1,9 +1,10 @@ from pypy.annotation.pairtype import pair, pairtype, extendabletype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython.lltype import Void, Bool, Float, Signed, Char, UniChar -from pypy.rpython.lltype import typeOf, LowLevelType, Ptr, PyObject -from pypy.rpython.lltype import FuncType, functionptr, cast_ptr_to_int +from pypy.rpython.lltypesystem.lltype import \ + Void, Bool, Float, Signed, Char, UniChar, \ + typeOf, LowLevelType, Ptr, PyObject, \ + FuncType, functionptr, cast_ptr_to_int from pypy.rpython.ootypesystem import ootype from pypy.rpython.error import TyperError, MissingRTypeOperation Modified: pypy/dist/pypy/rpython/robject.py ============================================================================== --- pypy/dist/pypy/rpython/robject.py (original) +++ pypy/dist/pypy/rpython/robject.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,7 @@ from pypy.annotation.pairtype import pair, pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltype import PyObject, Ptr, Void, Bool, pyobjectptr, nullptr +from pypy.rpython.lltypesystem.lltype import \ + PyObject, Ptr, Void, Bool, pyobjectptr, nullptr from pypy.rpython.rmodel import Repr, TyperError, VoidRepr, inputconst from pypy.rpython import rclass from pypy.tool.sourcetools import func_with_new_name Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Tue Oct 25 16:05:11 2005 @@ -4,8 +4,9 @@ from pypy.annotation import model as annmodel from pypy.annotation.classdef import isclassdef from pypy.objspace.flow.model import Constant -from pypy.rpython.lltype import typeOf, Void, ForwardReference, Struct, Bool -from pypy.rpython.lltype import Ptr, malloc, nullptr +from pypy.rpython.lltypesystem.lltype import \ + typeOf, Void, ForwardReference, Struct, Bool, \ + Ptr, malloc, nullptr from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning from pypy.rpython import rclass from pypy.rpython import robject Modified: pypy/dist/pypy/rpython/rptr.py ============================================================================== --- pypy/dist/pypy/rpython/rptr.py (original) +++ pypy/dist/pypy/rpython/rptr.py Tue Oct 25 16:05:11 2005 @@ -1,8 +1,8 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow import model as flowmodel -from pypy.rpython.lltype import Ptr, _ptr -from pypy.rpython.lltype import ContainerType, Void, Signed, Bool, FuncType, typeOf +from pypy.rpython.lltypesystem.lltype import \ + Ptr, _ptr, ContainerType, Void, Signed, Bool, FuncType, typeOf from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst Modified: pypy/dist/pypy/rpython/rrange.py ============================================================================== --- pypy/dist/pypy/rpython/rrange.py (original) +++ pypy/dist/pypy/rpython/rrange.py Tue Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, IteratorRepr -from pypy.rpython.lltype import Ptr, GcStruct, Signed, malloc, Void +from pypy.rpython.lltypesystem.lltype import Ptr, GcStruct, Signed, malloc, Void from pypy.objspace.flow.model import Constant from pypy.rpython.rlist import ll_newlist, dum_nocheck, dum_checkidx Modified: pypy/dist/pypy/rpython/rslice.py ============================================================================== --- pypy/dist/pypy/rpython/rslice.py (original) +++ pypy/dist/pypy/rpython/rslice.py Tue Oct 25 16:05:11 2005 @@ -3,7 +3,8 @@ from pypy.objspace.flow.model import Constant from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr import sys -from pypy.rpython.lltype import GcStruct, Signed, Ptr, Void,malloc +from pypy.rpython.lltypesystem.lltype import \ + GcStruct, Signed, Ptr, Void, malloc # ____________________________________________________________ # Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Tue Oct 25 16:05:11 2005 @@ -10,8 +10,9 @@ from pypy.rpython.rslice import SliceRepr from pypy.rpython.rslice import startstop_slice_repr, startonly_slice_repr from pypy.rpython.rslice import minusone_slice_repr -from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc -from pypy.rpython.lltype import Bool, Void, GcArray, nullptr, typeOf, pyobjectptr +from pypy.rpython.lltypesystem.lltype import \ + GcStruct, Signed, Array, Char, Ptr, malloc, \ + Bool, Void, GcArray, nullptr, typeOf, pyobjectptr # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/rtuple.py (original) +++ pypy/dist/pypy/rpython/rtuple.py Tue Oct 25 16:05:11 2005 @@ -4,8 +4,8 @@ from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst from pypy.rpython.rmodel import IteratorRepr from pypy.rpython.robject import PyObjRepr, pyobj_repr -from pypy.rpython.lltype import Ptr, GcStruct, Void, Signed, malloc -from pypy.rpython.lltype import typeOf, nullptr +from pypy.rpython.lltypesystem.lltype import \ + Ptr, GcStruct, Void, Signed, malloc, typeOf, nullptr # ____________________________________________________________ # Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Tue Oct 25 16:05:11 2005 @@ -18,10 +18,11 @@ from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, last_exception -from pypy.rpython.lltype import Signed, Unsigned, Float, Char, Bool, Void -from pypy.rpython.lltype import LowLevelType, Ptr, ContainerType -from pypy.rpython.lltype import FuncType, functionptr, typeOf, RuntimeTypeInfo -from pypy.rpython.lltype import attachRuntimeTypeInfo, Primitive +from pypy.rpython.lltypesystem.lltype import \ + Signed, Unsigned, Float, Char, Bool, Void, \ + LowLevelType, Ptr, ContainerType, \ + FuncType, functionptr, typeOf, RuntimeTypeInfo, \ + attachRuntimeTypeInfo, Primitive from pypy.rpython.ootypesystem import ootype from pypy.tool.sourcetools import func_with_new_name, valid_identifier from pypy.translator.unsimplify import insert_empty_block Modified: pypy/dist/pypy/rpython/test/test_exception.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_exception.py (original) +++ pypy/dist/pypy/rpython/test/test_exception.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.translator import Translator -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.test.test_llinterp import interpret Modified: pypy/dist/pypy/rpython/test/test_llann.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_llann.py (original) +++ pypy/dist/pypy/rpython/test/test_llann.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.annotation import model as annmodel from pypy.rpython.annlowlevel import annotate_lowlevel_helper from pypy.objspace.flow import FlowObjSpace 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 Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import py -from pypy.rpython.lltype import typeOf, pyobjectptr, Ptr, PyObject +from pypy.rpython.lltypesystem.lltype import typeOf, pyobjectptr, Ptr, PyObject from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.llinterp import LLInterpreter, LLException,log from pypy.translator.translator import Translator 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 Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * def isweak(p, T): return p._weak and typeOf(p).TO == T Modified: pypy/dist/pypy/rpython/test/test_normalizecalls.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_normalizecalls.py (original) +++ pypy/dist/pypy/rpython/test/test_normalizecalls.py Tue Oct 25 16:05:11 2005 @@ -2,7 +2,7 @@ from pypy.translator.translator import Translator from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.test.test_llinterp import interpret -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype def rtype(fn, argtypes=[]): Modified: pypy/dist/pypy/rpython/test/test_rbool.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rbool.py (original) +++ pypy/dist/pypy/rpython/test/test_rbool.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.translator import Translator -from pypy.rpython.lltype import pyobjectptr +from pypy.rpython.lltypesystem.lltype import pyobjectptr from pypy.rpython.rtyper import RPythonTyper from pypy.annotation import model as annmodel from pypy.rpython.test import snippet 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 Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.test import test_llinterp from pypy.rpython.objectmodel import instantiate, we_are_translated -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.objspace.flow import model as flowmodel from pypy.tool import udir 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 Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.translator import Translator -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.rarithmetic import intmask Modified: pypy/dist/pypy/rpython/test/test_rdict.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rdict.py (original) +++ pypy/dist/pypy/rpython/test/test_rdict.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.test.test_llinterp import interpret from pypy.rpython import rstr, rint, rdict Modified: pypy/dist/pypy/rpython/test/test_rexternalobj.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rexternalobj.py (original) +++ pypy/dist/pypy/rpython/test/test_rexternalobj.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.test_llinterp import interpret, gengraph from pypy.annotation.policy import AnnotatorPolicy 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 Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import sys from pypy.translator.translator import Translator -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.rlist import * from pypy.rpython.rslice import ll_newslice Modified: pypy/dist/pypy/rpython/test/test_robject.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_robject.py (original) +++ pypy/dist/pypy/rpython/test/test_robject.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.translator import Translator -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.test_llinterp import interpret 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 Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.translator import Translator -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.test.test_llinterp import interpret Modified: pypy/dist/pypy/rpython/test/test_rptr.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rptr.py (original) +++ pypy/dist/pypy/rpython/test/test_rptr.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ from pypy.translator.annrpython import RPythonAnnotator from pypy.rpython.annlowlevel import annotate_lowlevel_helper, LowLevelAnnotatorPolicy -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.rtyper import RPythonTyper from pypy.annotation import model as annmodel Modified: pypy/dist/pypy/rpython/test/test_rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rspecialcase.py (original) +++ pypy/dist/pypy/rpython/test/test_rspecialcase.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.test_llinterp import interpret, gengraph from pypy.translator.ann_override import PyPyAnnotatorPolicy 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 Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import random from pypy.translator.translator import Translator -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * 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 Modified: pypy/dist/pypy/rpython/test/test_rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rtuple.py (original) +++ pypy/dist/pypy/rpython/test/test_rtuple.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.translator import Translator -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.rtyper import RPythonTyper from pypy.rpython.rtuple import * from pypy.rpython.rint import signed_repr 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 Tue Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ from pypy.annotation import model as annmodel from pypy.translator.translator import Translator from pypy.translator import annrpython -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.test.test_llinterp import interpret from pypy.rpython.rtyper import RPythonTyper from pypy.rpython import rmodel Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Tue Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ import sys, os from pypy.objspace.flow.model import traverse, Block, Variable, Constant #from pypy.translator.asm import infregmachine -from pypy.rpython.lltype import Signed +from pypy.rpython.lltypesystem.lltype import Signed from pypy.translator.asm.simulator import Machine, TranslateProgram from pypy.translator.asm.model import * Modified: pypy/dist/pypy/translator/backendopt/inline.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/inline.py (original) +++ pypy/dist/pypy/translator/backendopt/inline.py Tue Oct 25 16:05:11 2005 @@ -6,7 +6,7 @@ from pypy.objspace.flow.model import SpaceOperation, last_exception from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Bool, typeOf, Void +from pypy.rpython.lltypesystem.lltype import Bool, typeOf, Void from pypy.rpython import rmodel from pypy.tool.algo import sparsemat from pypy.translator.backendopt.support import log Modified: pypy/dist/pypy/translator/backendopt/malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/malloc.py Tue Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link from pypy.objspace.flow.model import SpaceOperation, traverse, checkgraph from pypy.tool.algo.unionfind import UnionFind -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.simplify import remove_identical_vars from pypy.translator.backendopt.support import log Modified: pypy/dist/pypy/translator/backendopt/propagate.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/propagate.py (original) +++ pypy/dist/pypy/translator/backendopt/propagate.py Tue Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ from pypy.objspace.flow.model import Block, Variable, Constant, last_exception from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph from pypy.objspace.flow.model import SpaceOperation -from pypy.rpython.lltype import Void, Bool +from pypy.rpython.lltypesystem.lltype import Void, Bool from pypy.rpython.llinterp import LLInterpreter, LLFrame from pypy.translator import simplify from pypy.translator.backendopt.tailrecursion import get_graph Modified: pypy/dist/pypy/translator/backendopt/removenoops.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/removenoops.py (original) +++ pypy/dist/pypy/translator/backendopt/removenoops.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ from pypy.objspace.flow.model import Block, Variable, Constant from pypy.objspace.flow.model import traverse -from pypy.rpython.lltype import Void +from pypy.rpython.lltypesystem.lltype import Void def remove_same_as(graph): """Remove all 'same_as' operations. Modified: pypy/dist/pypy/translator/backendopt/tailrecursion.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/tailrecursion.py (original) +++ pypy/dist/pypy/translator/backendopt/tailrecursion.py Tue Oct 25 16:05:11 2005 @@ -5,7 +5,7 @@ from pypy.objspace.flow.model import SpaceOperation, last_exception from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph, flatten from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Bool, typeOf, FuncType, _ptr +from pypy.rpython.lltypesystem.lltype import Bool, typeOf, FuncType, _ptr # this transformation is very academical -- I had too much time Modified: pypy/dist/pypy/translator/backendopt/test/test_removenoops.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/test/test_removenoops.py (original) +++ pypy/dist/pypy/translator/backendopt/test/test_removenoops.py Tue Oct 25 16:05:11 2005 @@ -3,7 +3,7 @@ from pypy.translator.translator import Translator from pypy.translator.test.snippet import simple_method from pypy.objspace.flow.model import checkgraph, flatten, Block -from pypy.rpython.lltype import Void +from pypy.rpython.lltypesystem.lltype import Void from pypy.rpython.llinterp import LLInterpreter import py Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Tue Oct 25 16:05:11 2005 @@ -1,7 +1,8 @@ import sys -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.rpython.lltypesystem.lltype import \ + Primitive, Ptr, typeOf, RuntimeTypeInfo, \ + Struct, Array, FuncType, PyObject, Void, \ + 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 Modified: pypy/dist/pypy/translator/c/external.py ============================================================================== --- pypy/dist/pypy/translator/c/external.py (original) +++ pypy/dist/pypy/translator/c/external.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from __future__ import generators -from pypy.rpython.lltype import typeOf, Void +from pypy.rpython.lltypesystem.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 Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ import types -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.c.support import cdecl from pypy.rpython.rmodel import getfunctionptr from pypy.rpython.rstr import STR Modified: pypy/dist/pypy/translator/c/funcgen.py ============================================================================== --- pypy/dist/pypy/translator/c/funcgen.py (original) +++ pypy/dist/pypy/translator/c/funcgen.py Tue Oct 25 16:05:11 2005 @@ -4,8 +4,8 @@ from pypy.translator.c.support import llvalue_from_constant, gen_assignments from pypy.objspace.flow.model import Variable, Constant, Block from pypy.objspace.flow.model import traverse, last_exception -from pypy.rpython.lltype import Ptr, PyObject, Void, Bool -from pypy.rpython.lltype import pyobjectptr, Struct, Array +from pypy.rpython.lltypesystem.lltype import \ + Ptr, PyObject, Void, Bool, pyobjectptr, Struct, Array PyObjPtr = Ptr(PyObject) Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Tue Oct 25 16:05:11 2005 @@ -1,9 +1,9 @@ import sys 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 Array, GcArray, Struct, GcStruct -from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo +from pypy.rpython.lltypesystem.lltype import \ + typeOf, Ptr, PyObject, ContainerType, Array, GcArray, Struct, GcStruct, \ + RuntimeTypeInfo, getRuntimeTypeInfo PyObjPtr = Ptr(PyObject) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Tue Oct 25 16:05:11 2005 @@ -8,7 +8,7 @@ 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.rpython.lltypesystem import lltype from pypy.tool.udir import udir from pypy.translator.locality.calltree import CallTree Modified: pypy/dist/pypy/translator/c/node.py ============================================================================== --- pypy/dist/pypy/translator/c/node.py (original) +++ pypy/dist/pypy/translator/c/node.py Tue Oct 25 16:05:11 2005 @@ -1,8 +1,9 @@ from __future__ import generators -from pypy.rpython.lltype import Struct, Array, FuncType, PyObjectType, typeOf -from pypy.rpython.lltype import GcStruct, GcArray, GC_CONTAINER, ContainerType -from pypy.rpython.lltype import parentlink, Ptr, PyObject, Void, OpaqueType, Float -from pypy.rpython.lltype import RuntimeTypeInfo, getRuntimeTypeInfo, Char +from pypy.rpython.lltypesystem.lltype import \ + Struct, Array, FuncType, PyObjectType, typeOf, \ + GcStruct, GcArray, GC_CONTAINER, ContainerType, \ + parentlink, Ptr, PyObject, Void, OpaqueType, Float, \ + RuntimeTypeInfo, getRuntimeTypeInfo, Char 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 Modified: pypy/dist/pypy/translator/c/primitive.py ============================================================================== --- pypy/dist/pypy/translator/c/primitive.py (original) +++ pypy/dist/pypy/translator/c/primitive.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ import sys -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.rpython.memory.lladdress import Address, NULL # ____________________________________________________________ Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Tue Oct 25 16:05:11 2005 @@ -7,7 +7,7 @@ from pypy.translator.c.support import log from pypy.rpython.rarithmetic import r_int, r_uint -from pypy.rpython.lltype import pyobjectptr, LowLevelType +from pypy.rpython.lltypesystem.lltype import pyobjectptr, LowLevelType # XXX maybe this can be done more elegantly: # needed to convince should_translate_attr Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Tue Oct 25 16:05:11 2005 @@ -6,7 +6,7 @@ import py from pypy.objspace.flow.model import Variable -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.rpython.memory.lladdress import Address from pypy.translator.c.support import cdecl from pypy.translator.c.funcgen import FunctionCodeGenerator Modified: pypy/dist/pypy/translator/c/support.py ============================================================================== --- pypy/dist/pypy/translator/c/support.py (original) +++ pypy/dist/pypy/translator/c/support.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.gensupp import NameManager # Modified: pypy/dist/pypy/translator/c/symboltable.py ============================================================================== --- pypy/dist/pypy/translator/c/symboltable.py (original) +++ pypy/dist/pypy/translator/c/symboltable.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * class SymbolTable: 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 Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ import autopath, sys -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.translator.translator import Translator from pypy.translator.c.database import LowLevelDatabase from pypy.objspace.flow.model import Constant, Variable, SpaceOperation 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 Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ import autopath, sys, os, py -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.annotation import model as annmodel from pypy.translator.translator import Translator from pypy.translator.c.database import LowLevelDatabase Modified: pypy/dist/pypy/translator/c/test/test_lltyped.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_lltyped.py (original) +++ pypy/dist/pypy/translator/c/test/test_lltyped.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython.lltype import * +from pypy.rpython.lltypesystem.lltype import * from pypy.translator.tool.cbuild import skip_missing_compiler from pypy.translator.translator import Translator from pypy.objspace.flow import FlowObjSpace Modified: pypy/dist/pypy/translator/c/wrapper.py ============================================================================== --- pypy/dist/pypy/translator/c/wrapper.py (original) +++ pypy/dist/pypy/translator/c/wrapper.py Tue Oct 25 16:05:11 2005 @@ -1,8 +1,8 @@ from pypy.objspace.flow.model import Variable, Constant, SpaceOperation from pypy.objspace.flow.model import Block, Link, FunctionGraph, checkgraph from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Ptr, PyObject, typeOf, Signed, Void -from pypy.rpython.lltype import FuncType, functionptr +from pypy.rpython.lltypesystem.lltype import \ + Ptr, PyObject, typeOf, Signed, Void, FuncType, functionptr from pypy.rpython.rtyper import LowLevelOpList from pypy.rpython.rmodel import inputconst, getfunctionptr, PyObjPtr from pypy.rpython.robject import pyobj_repr Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ import py -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.js.node import LLVMNode, ConstantLLVMNode from pypy.translator.js.log import log log = log.structnode Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Tue Oct 25 16:05:11 2005 @@ -7,7 +7,7 @@ from pypy.translator.js.arraynode import ArrayNode, StrArrayNode, VoidArrayNode from pypy.translator.js.opaquenode import OpaqueNode from pypy.translator.js.node import ConstantLLVMNode -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.objspace.flow.model import Constant, Variable from pypy.translator.js.log import log Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Tue Oct 25 16:05:11 2005 @@ -2,7 +2,7 @@ import sys from pypy.objspace.flow.model import Block, Constant, Variable, Link from pypy.objspace.flow.model import flatten, mkentrymap, traverse, last_exception -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.js.node import LLVMNode, ConstantLLVMNode from pypy.translator.js.opwriter import OpWriter from pypy.translator.js.log import log Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Tue Oct 25 16:05:11 2005 @@ -15,7 +15,7 @@ import py from pypy.rpython.rmodel import inputconst, getfunctionptr -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.tool.udir import udir from pypy.translator.js.node import LLVMNode from pypy.translator.js.database import Database Modified: pypy/dist/pypy/translator/js/node.py ============================================================================== --- pypy/dist/pypy/translator/js/node.py (original) +++ pypy/dist/pypy/translator/js/node.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype _nodename_count = {} Modified: pypy/dist/pypy/translator/js/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/js/opaquenode.py (original) +++ pypy/dist/pypy/translator/js/opaquenode.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.js.node import LLVMNode, ConstantLLVMNode -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype class OpaqueNode(ConstantLLVMNode): Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import py from pypy.objspace.flow.model import Constant -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype #from pypy.translator.js.module.extfunction import extfunctions from pypy.translator.js.extfuncnode import ExternalFuncNode from pypy.translator.js.log import log Modified: pypy/dist/pypy/translator/js/structnode.py ============================================================================== --- pypy/dist/pypy/translator/js/structnode.py (original) +++ pypy/dist/pypy/translator/js/structnode.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import py from pypy.translator.js.node import LLVMNode, ConstantLLVMNode -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.js.log import log log = log.structnode Modified: pypy/dist/pypy/translator/js/test/test_lltype.py ============================================================================== --- pypy/dist/pypy/translator/js/test/test_lltype.py (original) +++ pypy/dist/pypy/translator/js/test/test_lltype.py Tue Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ import py -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.js.test.runtest import compile_function from pypy.translator.js import database, codewriter Modified: pypy/dist/pypy/translator/llvm/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm/arraynode.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ import py -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.log import log from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode from pypy.translator.llvm import varsize Modified: pypy/dist/pypy/translator/llvm/backendopt/exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm/backendopt/exception.py (original) +++ pypy/dist/pypy/translator/llvm/backendopt/exception.py Tue Oct 25 16:05:11 2005 @@ -2,7 +2,7 @@ from pypy.objspace.flow.model import Block, Constant, Variable, Link, \ last_exception, flatten, SpaceOperation from pypy.annotation import model as annmodel -from pypy.rpython.lltype import Bool, Ptr +from pypy.rpython.lltypesystem.lltype import Bool, Ptr n_calls = n_calls_patched = 0 Modified: pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py ============================================================================== --- pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py (original) +++ pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.objspace.flow.model import Block, flatten, SpaceOperation, Constant, Variable -from pypy.rpython.lltype import Struct, GcStruct, Void, Ptr +from pypy.rpython.lltypesystem.lltype import Struct, GcStruct, Void, Ptr from pypy.translator.llvm.backendopt.support import log Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Tue Oct 25 16:05:11 2005 @@ -10,7 +10,7 @@ VoidArrayNode, ArrayTypeNode, VoidArrayTypeNode from pypy.translator.llvm.opaquenode import OpaqueNode, OpaqueTypeNode from pypy.translator.llvm.node import ConstantLLVMNode -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.objspace.flow.model import Constant, Variable log = log.database Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Tue Oct 25 16:05:11 2005 @@ -4,7 +4,7 @@ import urllib from pypy.rpython.rmodel import inputconst, getfunctionptr -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.codewriter import CodeWriter, \ DEFAULT_TAIL, DEFAULT_CCONV Modified: pypy/dist/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm/funcnode.py Tue Oct 25 16:05:11 2005 @@ -2,7 +2,7 @@ import sys from pypy.objspace.flow.model import Block, Constant, Variable, Link from pypy.objspace.flow.model import flatten, mkentrymap, traverse, last_exception -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode from pypy.translator.llvm.opwriter import OpWriter from pypy.translator.llvm.log import log Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Tue Oct 25 16:05:11 2005 @@ -9,7 +9,7 @@ from pypy.translator.llvm.database import Database from pypy.translator.llvm.pyxwrapper import write_pyx_wrapper from pypy.rpython.rmodel import inputconst, getfunctionptr -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.tool.udir import udir from pypy.translator.llvm.codewriter import CodeWriter, \ DEFAULT_TAIL, DEFAULT_CCONV Modified: pypy/dist/pypy/translator/llvm/node.py ============================================================================== --- pypy/dist/pypy/translator/llvm/node.py (original) +++ pypy/dist/pypy/translator/llvm/node.py Tue Oct 25 16:05:11 2005 @@ -1,4 +1,4 @@ -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype class LLVMNode(object): __slots__ = "".split() Modified: pypy/dist/pypy/translator/llvm/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opaquenode.py (original) +++ pypy/dist/pypy/translator/llvm/opaquenode.py Tue Oct 25 16:05:11 2005 @@ -1,5 +1,5 @@ from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype class OpaqueTypeNode(LLVMNode): Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import py from pypy.objspace.flow.model import Constant -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.module.extfunction import extfunctions from pypy.translator.llvm.extfuncnode import ExternalFuncNode from pypy.translator.llvm.log import log Modified: pypy/dist/pypy/translator/llvm/pyxwrapper.py ============================================================================== --- pypy/dist/pypy/translator/llvm/pyxwrapper.py (original) +++ pypy/dist/pypy/translator/llvm/pyxwrapper.py Tue Oct 25 16:05:11 2005 @@ -1,6 +1,6 @@ import sys from pypy.translator.llvm.log import log -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype log = log.pyrex PRIMITIVES_TO_C = {lltype.Bool: "char", Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Tue Oct 25 16:05:11 2005 @@ -2,7 +2,7 @@ from pypy.translator.llvm.log import log from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode from pypy.translator.llvm import varsize -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype log = log.structnode 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 Tue Oct 25 16:05:11 2005 @@ -1,7 +1,7 @@ import py -from pypy.rpython import lltype +from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.llvm import database, codewriter Modified: pypy/dist/pypy/translator/simplify.py ============================================================================== --- pypy/dist/pypy/translator/simplify.py (original) +++ pypy/dist/pypy/translator/simplify.py Tue Oct 25 16:05:11 2005 @@ -14,7 +14,7 @@ if isinstance(arg, Variable): return None f = arg.value - from pypy.rpython import lltype + from pypy.rpython.lltypesystem import lltype if not isinstance(f, lltype._ptr): return None try: From hpk at codespeak.net Tue Oct 25 16:12:11 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Tue, 25 Oct 2005 16:12:11 +0200 (CEST) Subject: [pypy-svn] r18935 - pypy/dist/pypy/doc Message-ID: <20051025141211.E77A027B76@code1.codespeak.net> Author: hpk Date: Tue Oct 25 16:12:11 2005 New Revision: 18935 Modified: pypy/dist/pypy/doc/_ref.txt Log: rengerated references Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Tue Oct 25 16:12:11 2005 @@ -41,8 +41,6 @@ .. _`pypy/rpython`: .. _`rpython/`: ../../pypy/rpython .. _`pypy/rpython/extfunctable.py`: ../../pypy/rpython/extfunctable.py -.. _`pypy/rpython/lltype.py`: -.. _`rpython/lltype.py`: ../../pypy/rpython/lltype.py .. _`rpython/memory/`: ../../pypy/rpython/memory .. _`pypy/rpython/memory/gc.py`: ../../pypy/rpython/memory/gc.py .. _`pypy/rpython/memory/lladdress.py`: ../../pypy/rpython/memory/lladdress.py From mwh at codespeak.net Tue Oct 25 16:30:39 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 25 Oct 2005 16:30:39 +0200 (CEST) Subject: [pypy-svn] r18939 - pypy/dist/pypy/doc Message-ID: <20051025143039.ED92127B5F@code1.codespeak.net> Author: mwh Date: Tue Oct 25 16:30:38 2005 New Revision: 18939 Modified: pypy/dist/pypy/doc/_ref.txt pypy/dist/pypy/doc/getting-started-0.8.txt pypy/dist/pypy/doc/getting-started.txt pypy/dist/pypy/doc/translation.txt Log: fix references to rpython.lltype in the docs. Modified: pypy/dist/pypy/doc/_ref.txt ============================================================================== --- pypy/dist/pypy/doc/_ref.txt (original) +++ pypy/dist/pypy/doc/_ref.txt Tue Oct 25 16:30:38 2005 @@ -41,6 +41,8 @@ .. _`pypy/rpython`: .. _`rpython/`: ../../pypy/rpython .. _`pypy/rpython/extfunctable.py`: ../../pypy/rpython/extfunctable.py +.. _`pypy/rpython/lltypesystem/lltype.py`: +.. _`rpython/lltypesystem/lltype.py`: ../../pypy/rpython/lltypesystem/lltype.py .. _`rpython/memory/`: ../../pypy/rpython/memory .. _`pypy/rpython/memory/gc.py`: ../../pypy/rpython/memory/gc.py .. _`pypy/rpython/memory/lladdress.py`: ../../pypy/rpython/memory/lladdress.py Modified: pypy/dist/pypy/doc/getting-started-0.8.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started-0.8.txt (original) +++ pypy/dist/pypy/doc/getting-started-0.8.txt Tue Oct 25 16:30:38 2005 @@ -547,8 +547,9 @@ 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. + be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + there is a file rxxxx.py that contains the low level functions needed for + this type. .. _optionaltool: Modified: pypy/dist/pypy/doc/getting-started.txt ============================================================================== --- pypy/dist/pypy/doc/getting-started.txt (original) +++ pypy/dist/pypy/doc/getting-started.txt Tue Oct 25 16:30:38 2005 @@ -523,8 +523,9 @@ 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. + be found in `pypy/rpython/lltypesystem/lltype.py`_. For each RPython type + there is a file rxxxx.py that contains the low level functions needed for + this type. .. _optionaltool: Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Tue Oct 25 16:30:38 2005 @@ -485,10 +485,10 @@ where -- in C notation -- all three variables v1, v2 and v3 are typed ``int``. This is done by attaching an attribute ``concretetype`` to v1, v2 and v3 (which might be instances of Variable or possibly Constant). In our model, -this ``concretetype`` is ``pypy.rpython.lltype.Signed``. Of course, the -purpose of replacing the operation called ``add`` with ``int_add`` is that -code generators no longer have to worry about what kind of addition (or -concatenation maybe?) it means. +this ``concretetype`` is ``pypy.rpython.lltypesystem.lltype.Signed``. Of +course, the purpose of replacing the operation called ``add`` with +``int_add`` is that code generators no longer have to worry about what kind +of addition (or concatenation maybe?) it means. The process in more details @@ -563,13 +563,14 @@ 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. -This model is implemented in the first part of `rpython/lltype.py`_. +This model is implemented in the first part of +`rpython/lltypesystem/lltype.py`_. -The second part of `rpython/lltype.py`_ is a runnable implementation of these -types, for testing purposes. It allows us to write and test plain Python code -using a malloc() function to obtain and manipulate structures and arrays. -This is useful for example to implement and test RPython types like 'list' with -its operations and methods. +The second part of `rpython/lltypesystem/lltype.py`_ is a runnable +implementation of these types, for testing purposes. It allows us to write +and test plain Python code using a malloc() function to obtain and manipulate +structures and arrays. This is useful for example to implement and test +RPython types like 'list' with its operations and methods. The basic assumption is that Variables (i.e. local variables and function arguments and return value) all contain "simple" values: basically, just @@ -624,9 +625,9 @@ a very limited, easily controllable set of types, and define implementations of types like list in this elementary world. The ``malloc()`` function is a kind of placeholder, which must eventually be provided by the code generator for the -target platform; but as we have just seen its Python implementation in -`rpython/lltype.py`_ works too, which is primarily useful for testing, -interactive exploring, etc. +target platform; but as we have just seen its Python implementation in +`rpython/lltypesystem/lltype.py`_ works too, which is primarily useful for +testing, interactive exploring, etc. The argument to ``malloc()`` is the structure type directly, but it returns a pointer to the structure, as ``typeOf()`` tells you:: @@ -678,7 +679,8 @@ Structure Types +++++++++++++++ -Structure types are built as instances of ``pypy.rpython.lltype.Struct``:: +Structure types are built as instances of +``pypy.rpython.lltypesystem.lltype.Struct``:: MyStructType = Struct('somename', ('field1', Type1), ('field2', Type2)...) MyStructType = GcStruct('somename', ('field1', Type1), ('field2', Type2)...) @@ -709,7 +711,8 @@ Array Types +++++++++++ -An array type is built as an instance of ``pypy.rpython.lltype.Array``:: +An array type is built as an instance of +``pypy.rpython.lltypesystem.lltype.Array``:: MyIntArray = Array(Signed) MyOtherArray = Array(MyItemType) @@ -748,11 +751,11 @@ with care: the bigger structure of which they are part of could be freed while the Ptr to the substructure is still in use. In general, it is a good idea to avoid passing around pointers to inlined substructures of malloc()ed structures. -(The testing implementation of `rpython/lltype.py`_ checks to some extend that -you are not trying to use a pointer to a structure after its container has been -freed, using weak references. But pointers to non-GC structures are not -officially meant to be weak references: using them after what they point to has -been freed just crashes.) +(The testing implementation of `rpython/lltypesystem/lltype.py`_ checks to some +extent that you are not trying to use a pointer to a structure after its +container has been freed, using weak references. But pointers to non-GC +structures are not officially meant to be weak references: using them after what +they point to has been freed just crashes.) The malloc() operation allocates and returns a Ptr to a new GC structure or array. In a refcounting implementation, malloc() would allocate enough space From pedronis at codespeak.net Tue Oct 25 16:41:23 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 25 Oct 2005 16:41:23 +0200 (CEST) Subject: [pypy-svn] r18940 - in pypy/dist/pypy: module/_socket/rpython rpython/module Message-ID: <20051025144123.8EEA127B66@code1.codespeak.net> Author: pedronis Date: Tue Oct 25 16:41:22 2005 New Revision: 18940 Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py pypy/dist/pypy/rpython/module/ll_stackless.py Log: fix lltype imports Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Tue Oct 25 16:41:22 2005 @@ -1,7 +1,7 @@ import _socket from pypy.rpython.rstr import STR -from pypy.rpython.lltype import GcStruct, Signed, Array, Char, Ptr, malloc +from pypy.rpython.lltypesystem.lltype import GcStruct, Signed, Array, Char, Ptr, malloc from pypy.rpython.module.support import to_rstr, from_rstr from pypy.rpython.module.support import to_opaque_object, from_opaque_object from pypy.module._socket.rpython import rsocket Modified: pypy/dist/pypy/rpython/module/ll_stackless.py ============================================================================== --- pypy/dist/pypy/rpython/module/ll_stackless.py (original) +++ pypy/dist/pypy/rpython/module/ll_stackless.py Tue Oct 25 16:41:22 2005 @@ -1,4 +1,5 @@ -from pypy.rpython import rstack, lltype, extfunctable +from pypy.rpython.lltypesystem import lltype +from pypy.rpython import rstack, extfunctable from pypy.rpython.module.support import from_opaque_object, to_opaque_object FRAMETOPTYPE = extfunctable.frametop_type_info.get_lltype() From pedronis at codespeak.net Tue Oct 25 18:10:03 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Tue, 25 Oct 2005 18:10:03 +0200 (CEST) Subject: [pypy-svn] r18953 - pypy/dist/pypy/doc Message-ID: <20051025161003.6531527B76@code1.codespeak.net> Author: pedronis Date: Tue Oct 25 18:10:02 2005 New Revision: 18953 Added: pypy/dist/pypy/doc/release-0.8.0.txt - copied unchanged from r18950, pypy/dist/pypy/doc/release-0.7.0.txt Log: make a copy of the prev rel announcement as baseline for the next one, we need to discuss and decide what to highlight! From afa at codespeak.net Tue Oct 25 20:10:28 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 25 Oct 2005 20:10:28 +0200 (CEST) Subject: [pypy-svn] r18970 - in pypy/dist/pypy/module/_socket: . rpython Message-ID: <20051025181028.215FB27B61@code1.codespeak.net> Author: afa Date: Tue Oct 25 20:10:22 2005 New Revision: 18970 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/rpython/rsocket.py Log: Yet another correction for socket.getaddrinfo() Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Tue Oct 25 20:10:22 2005 @@ -328,9 +328,11 @@ def enumerateaddrinfo(space, addr): result = [] - while addr.nextinfo(): - info = (addr.family, addr.socktype, addr.proto, - addr.canonname, addr.sockaddr) + while True: + addrinfo = addr.nextinfo() + if addrinfo[0] == 0: + break + info = addrinfo[:4] + (addrinfo[4:],) result.append(space.wrap(info)) return space.newlist(result) Modified: pypy/dist/pypy/module/_socket/rpython/rsocket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/rsocket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/rsocket.py Tue Oct 25 20:10:22 2005 @@ -1,26 +1,27 @@ """ -Helper file for Python equivalents of os specific calls. +Helper file for Python equivalents of socket specific calls. """ import socket class ADDRINFO(object): + # a simulated addrinfo structure from C, i.e. a chained list + # returned by getaddrinfo() def __init__(self, host, port, family, socktype, proto, flags): - self._entries = iter(socket.getaddrinfo( - host, port, family, socktype, proto, flags)) - + addrinfo = socket.getaddrinfo(host, port, + family, socktype, proto, flags) + self._entries = iter(addrinfo) + def nextinfo(self): try: info = self._entries.next() except StopIteration: - return None - (self.family, self.socktype, self.proto, - self.canonname, self.sockaddr) = info - return info[:4] + info[4] + return [0] * 8 + + return info[:-1] + info[-1] def free(self): pass - def getaddrinfo(host, port, family, socktype, proto, flags): return ADDRINFO(host, port, family, socktype, proto, flags) From mwh at codespeak.net Tue Oct 25 21:01:52 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 25 Oct 2005 21:01:52 +0200 (CEST) Subject: [pypy-svn] r18971 - pypy/dist/pypy/annotation Message-ID: <20051025190152.F408127B61@code1.codespeak.net> Author: mwh Date: Tue Oct 25 21:01:52 2005 New Revision: 18971 Modified: pypy/dist/pypy/annotation/model.py Log: local imports are bad, mmkay? Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Tue Oct 25 21:01:52 2005 @@ -501,7 +501,7 @@ if v is None: # i think we can only get here in the case of void-returning # functions - from bookkeeper import getbookkeeper + from pypy.annotation.bookkeeper import getbookkeeper return getbookkeeper().immutablevalue(None) if isinstance(v, MethodType): ll_ptrtype = lltype.typeOf(v.im_self) From mwh at codespeak.net Tue Oct 25 21:08:25 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Tue, 25 Oct 2005 21:08:25 +0200 (CEST) Subject: [pypy-svn] r18972 - pypy/dist/pypy/tool Message-ID: <20051025190825.BE52B27B5A@code1.codespeak.net> Author: mwh Date: Tue Oct 25 21:08:24 2005 New Revision: 18972 Added: pypy/dist/pypy/tool/importfun.py Log: a prototypical import analyser. it's reasonably smart, but currently can't analyse all of pypy because it doesn't support the "import pygame.locals" style of import statement. i'll get to it tomorrow, run out of time for today... you probably don't want to read the code :) Added: pypy/dist/pypy/tool/importfun.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/tool/importfun.py Tue Oct 25 21:08:24 2005 @@ -0,0 +1,288 @@ +import sys +import opcode +import dis +import imp +from sys import path, prefix + +""" +so design goal: + +i want to take a pile of source code and analyze each module for the +names it defines and the modules it imports and the names it uses from +them. + +then i can find things like: + +- things which are just plain not used anywhere +- things which are defined in one module and only used in another +- importing of names from modules where they are just imported from + somewhere else +- cycles in the import graph +- unecessary imports + +finding imports at top level is fairly easy, although the variety of +types of import statement can be baffling. a mini reference: + +import foo + +-> + +LOAD_CONST None +IMPORT_NAME foo +STORE_NAME foo + + +import foo as bar + +-> + +LOAD_CONST None +IMPORT_NAME foo +STORE_NAME bar + +from foo import bar + +-> + +LOAD_CONST ('bar',) +IMPORT_NAME foo +IMPORT_FROM bar +STORE_NAME bar +POP_TOP + +from foo import bar, baz + +-> + +LOAD_CONST ('bar','baz') +IMPORT_NAME foo +IMPORT_FROM bar +STORE_NAME bar +IMPORT_FROM baz +STORE_NAME baz +POP_TOP + +from foo.baz import bar + +-> + +LOAD_CONST ('bar',) +IMPORT_NAME foo.baz +IMPORT_FROM bar +STORE_NAME bar +POP_TOP + + +there are other forms, but i don't support them (should hit an +assertion rather than silently fail). + +""" + +class System: + def __init__(self): + self.modules = {} + self.pendingmodules = {} + +class Scope(object): + def __init__(self, parent=None): + self.modvars = {} # varname -> absolute module name + self.parent = parent + self.varsources = {} + + def mod_for_name(self, name): + if name in self.modvars: + return self.modvars[name] + elif self.parent is not None: + return self.parent.mod_for_name(name) + else: + return None + + def var_source(self, name): + if name in self.varsources: + return self.varsources[name] + elif self.parent is not None: + return self.parent.var_source(name) + else: + return None, None + + +class Module(object): + def __init__(self, system): + self.system = system + self.imports = {} # {modname:{name:was-it-used?}} + self.definitions = [] + self.toplevelscope = Scope() + + +def iteropcodes(codestring): + n = len(codestring) + i = 0 + while i < n: + op = ord(codestring[i]) + i += 1 + oparg = None + assert op != opcode.EXTENDED_ARG + if op >= opcode.HAVE_ARGUMENT: + oparg = ord(codestring[i]) + ord(codestring[i+1])*256 + i += 2 + yield op, oparg + +STORE_DEREF = opcode.opmap["STORE_DEREF"] +STORE_FAST = opcode.opmap["STORE_FAST"] +STORE_GLOBAL = opcode.opmap["STORE_GLOBAL"] +STORE_NAME = opcode.opmap["STORE_NAME"] +IMPORT_NAME = opcode.opmap["IMPORT_NAME"] +IMPORT_FROM = opcode.opmap["IMPORT_FROM"] +LOAD_CONST = opcode.opmap["LOAD_CONST"] +LOAD_ATTR = opcode.opmap["LOAD_ATTR"] + +LOAD_FAST = opcode.opmap["LOAD_FAST"] +LOAD_NAME = opcode.opmap["LOAD_NAME"] +LOAD_GLOBAL = opcode.opmap["LOAD_GLOBAL"] + +MAKE_CLOSURE = opcode.opmap["MAKE_CLOSURE"] +MAKE_FUNCTION = opcode.opmap["MAKE_FUNCTION"] + +POP_TOP = opcode.opmap['POP_TOP'] + +def process(r, codeob, scope, toplevel=False): + opcodes = list(iteropcodes(codeob.co_code)) + + i = 0 + + codeobjs = [] + + while i < len(opcodes): + op, oparg = opcodes[i] + + if op == IMPORT_NAME: + preop, preoparg = opcodes[i-1] + assert preop == LOAD_CONST + + fromlist = codeob.co_consts[preoparg] + + modname = codeob.co_names[oparg] + + if fromlist is None: + # this is the 'import foo' case + if modname not in r.imports: + if modname not in r.system.modules: + r.system.pendingmodules[modname] = None + r.imports[modname] = {} + + postop, postoparg = opcodes[i+1] + + # ban 'import foo.bar' (it's dubious style anyway, imho) + + assert not '.' in modname + + scope.modvars[codeob.co_names[postoparg]] = modname + i += 1 + elif fromlist == ('*',): + pass + else: + # ok, this is from foo import bar + path = None + for part in modname.split('.'): + path = [imp.find_module(part, path)[1]] +# assert '.' not in codeob.co_names[oparg] + i += 1 + vars = mods = None + for f in fromlist: + op, oparg = opcodes[i] + assert op == IMPORT_FROM + assert codeob.co_names[oparg] == f + i += 1 + + try: + imp.find_module(f, path) + except ImportError: + assert mods is None + vars = True + if modname not in r.imports: + if modname not in r.system.modules: + r.system.pendingmodules[modname] = None + r.imports[modname] = {} + r.imports[modname][f] = False + else: + assert vars is None + mods = True + submod = modname + '.' + f + if submod not in r.imports: + if submod not in r.system.modules: + r.system.pendingmodules[submod] = None + r.imports[submod] = {} + + op, oparg = opcodes[i] + + assert op in [STORE_NAME, STORE_FAST, STORE_DEREF] + + if mods is not None: + scope.modvars[codeob.co_names[oparg]] = submod + else: + scope.varsources[codeob.co_names[oparg]] = modname, f + i += 1 + op, oparg = opcodes[i] + assert op == POP_TOP + elif op == STORE_NAME and toplevel or op == STORE_GLOBAL: + r.definitions.append(codeob.co_names[oparg]) + elif op == LOAD_ATTR: + preop, preoparg = opcodes[i-1] + if preop in [LOAD_FAST, LOAD_NAME, LOAD_GLOBAL]: + m = scope.mod_for_name(codeob.co_names[preoparg]) + if m: + r.imports[m][codeob.co_names[oparg]] = True + elif op in [LOAD_NAME, LOAD_GLOBAL]: + name = codeob.co_names[oparg] + m, a = scope.var_source(name) + if m: + assert a in r.imports[m] + r.imports[m][a] = True + elif op in [LOAD_FAST]: + name = codeob.co_varnames[oparg] + m, a = scope.var_source(name) + if m: + assert a in r.imports[m] + r.imports[m][a] = True + elif op in [MAKE_FUNCTION, MAKE_CLOSURE]: + preop, preoparg = opcodes[i-1] + assert preop == LOAD_CONST + codeobjs.append(codeob.co_consts[preoparg]) + + i += 1 + for c in codeobjs: + process(r, c, Scope(scope)) + +def process_module(dottedname, system): + path = find_from_dotted_name(dottedname) + code = compile(open(path).read(), '', 'exec') + r = Module(system) + + process(r, code, r.toplevelscope, True) + + assert dottedname not in system.pendingmodules + + system.modules[dottedname] = r + + return r + +a = 1 + +def find_from_dotted_name(modname): + path = None + for part in modname.split('.'): + path = [imp.find_module(part, path)[1]] + return path[0] + +def main(path): + system = System() + system.pendingmodules[path] = None + while system.pendingmodules: + path, d = system.pendingmodules.popitem() + print len(system.pendingmodules), path + if not path.startswith('pypy.'): + continue + process_module(path, system) + +if __name__=='__main__': + main(*sys.argv[1:]) From afa at codespeak.net Tue Oct 25 21:34:26 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Tue, 25 Oct 2005 21:34:26 +0200 (CEST) Subject: [pypy-svn] r18973 - in pypy/dist/pypy/translator/c: src test Message-ID: <20051025193426.4E73127B5C@code1.codespeak.net> Author: afa Date: Tue Oct 25 21:34:16 2005 New Revision: 18973 Modified: pypy/dist/pypy/translator/c/src/ll__socket.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: socket.getaddrinfo(): Found a way to decref a rstring, and test passes. Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Tue Oct 25 21:34:16 2005 @@ -153,8 +153,10 @@ canonname, ipaddr, // XXX AF_INET Only! ntohs(a->sin_port),0,0); - // XXX DECREF(canonname) - // XXX DECREF(ipaddr) +#if !defined(USING_BOEHM_GC) && !defined(USING_NO_GC) + canonname->refcount--; + ipaddr->refcount--; +#endif return ret; } } 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 Oct 25 21:34:16 2005 @@ -563,9 +563,6 @@ assert res == _socket.gethostname() def test_getaddrinfo(): - py.test.skip("In progress") - # XXX fails on 'assert mallocs == frees' - # needs a way to decref rstrings from ll__socket.h import pypy.module._socket.rpython.exttable # for declare()/declaretype() from pypy.module._socket.rpython import rsocket def does_stuff(host, port): From afa at codespeak.net Wed Oct 26 00:08:01 2005 From: afa at codespeak.net (afa at codespeak.net) Date: Wed, 26 Oct 2005 00:08:01 +0200 (CEST) Subject: [pypy-svn] r18976 - in pypy/dist/pypy: module/_socket module/_socket/rpython translator/c translator/c/src translator/c/test Message-ID: <20051025220801.A130127B5F@code1.codespeak.net> Author: afa Date: Wed Oct 26 00:07:50 2005 New Revision: 18976 Modified: pypy/dist/pypy/module/_socket/interp_socket.py pypy/dist/pypy/module/_socket/rpython/exttable.py pypy/dist/pypy/module/_socket/rpython/ll__socket.py pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll__socket.h pypy/dist/pypy/translator/c/test/test_extfunc.py Log: Some corrections for the _socket module declarations + added gethostbyname() - Locking macros are commented out - need support functions to raise exceptions correctly Modified: pypy/dist/pypy/module/_socket/interp_socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/interp_socket.py (original) +++ pypy/dist/pypy/module/_socket/interp_socket.py Wed Oct 26 00:07:50 2005 @@ -6,6 +6,9 @@ from pypy.interpreter.gateway import ObjSpace, interp2app from pypy.module._socket.rpython import rsocket +# Force the declarations of external functions +import pypy.module.thread.rpython.exttable + if sys.platform == 'win32': WIN32_ERROR_MESSAGES = { errno.WSAEINTR: "Interrupted system call", @@ -768,7 +771,7 @@ method = getattr(Socket, methodname) assert hasattr(method,'unwrap_spec'), methodname assert method.im_func.func_code.co_argcount == len(method.unwrap_spec), methodname - socketmethods[methodname] = interp2app(method, method.unwrap_spec) + socketmethods[methodname] = interp2app(method, unwrap_spec=method.unwrap_spec) Socket.typedef = TypeDef("_socket.socket", __doc__ = """\ Modified: pypy/dist/pypy/module/_socket/rpython/exttable.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/exttable.py (original) +++ pypy/dist/pypy/module/_socket/rpython/exttable.py Wed Oct 26 00:07:50 2005 @@ -4,10 +4,9 @@ import _socket from pypy.module._socket.rpython import rsocket -from pypy.rpython.extfunctable import declare, declareptrtype -from pypy.annotation.model import Constant, SomeTuple, SomeList, SomeInteger, SomeString -from pypy.annotation.listdef import ListDef -from pypy.annotation.model import unionof +from pypy.rpython.extfunctable import declare, declaretype, declareptrtype +from pypy.rpython.extfunctable import standardexceptions +from pypy.annotation.model import SomeTuple, SomeInteger, SomeString module = 'pypy.module._socket.rpython.ll__socket' @@ -29,6 +28,7 @@ return addrinfo declare(_socket.gethostname, str, '%s/gethostname' % module) +declare(_socket.gethostbyname, str, '%s/gethostbyname' % module) declare(rsocket.getaddrinfo, rsocket.ADDRINFO, '%s/getaddrinfo' % module) declareptrtype(rsocket.ADDRINFO, "ADDRINFO", @@ -39,3 +39,9 @@ declare(_socket.htons, int, '%s/ntohs' % module) declare(_socket.ntohl, int, '%s/ntohl' % module) declare(_socket.htonl, int, '%s/htonl' % module) + +# ____________________________________________________________ +# _socket.error can be raised by the above + +# XXX a bit hackish +standardexceptions[_socket.error] = True Modified: pypy/dist/pypy/module/_socket/rpython/ll__socket.py ============================================================================== --- pypy/dist/pypy/module/_socket/rpython/ll__socket.py (original) +++ pypy/dist/pypy/module/_socket/rpython/ll__socket.py Wed Oct 26 00:07:50 2005 @@ -10,6 +10,10 @@ return to_rstr(_socket.gethostname()) ll__socket_gethostname.suggested_primitive = True +def ll__socket_gethostbyname(name): + return to_rstr(_socket.gethostbyname(name)) +ll__socket_gethostbyname.suggested_primitive = True + def ll__socket_getaddrinfo(host, port, family, socktype, proto, flags): addr = rsocket.getaddrinfo(from_rstr(host), port, family, socktype, proto, flags) Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Wed Oct 26 00:07:50 2005 @@ -58,10 +58,11 @@ ll_stackless.ll_stackless_stack_frames_depth: 'LL_stackless_stack_frames_depth', ll_stack.ll_stack_unwind: 'LL_stack_unwind', ll_stack.ll_stack_too_big: 'LL_stack_too_big', - ll__socket.ll__socket_gethostname: 'LL__socket_gethostname', - ll__socket.ll__socket_getaddrinfo: 'LL__socket_getaddrinfo', - ll__socket.ll__socket_nextaddrinfo: 'LL__socket_nextaddrinfo', - ll__socket.ll__socket_freeaddrinfo: 'LL__socket_freeaddrinfo', + ll__socket.ll__socket_gethostname: 'LL__socket_gethostname', + ll__socket.ll__socket_gethostbyname: 'LL__socket_gethostbyname', + ll__socket.ll__socket_getaddrinfo: 'LL__socket_getaddrinfo', + ll__socket.ll__socket_nextaddrinfo: 'LL__socket_nextaddrinfo', + ll__socket.ll__socket_freeaddrinfo: 'LL__socket_freeaddrinfo', ll__socket.ll__socket_ntohs: 'LL__socket_ntohs', ll__socket.ll__socket_htons: 'LL__socket_htons', ll__socket.ll__socket_htonl: 'LL__socket_htonl', Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Wed Oct 26 00:07:50 2005 @@ -13,6 +13,7 @@ long LL__socket_ntohl(long htonl); long LL__socket_htonl(long ntohl); RPyString *LL__socket_gethostname(void); +RPyString *LL__socket_gethostbyname(RPyString *name); struct RPyOpaque_ADDRINFO *LL__socket_getaddrinfo(RPyString *host, RPyString *port, int family, int socktype, int proto, int flags); @@ -73,15 +74,181 @@ return htonl(ntohl); } +/* ____________________________________________________________________________ */ + +/* Lock to allow python interpreter to continue, but only allow one + thread to be in gethostbyname or getaddrinfo */ +#if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK) +/* XXX */ +/* RPyThread_type_lock netdb_lock; */ +#endif + +#ifdef USE_GETADDRINFO_LOCK +/* XXX not used */ +/* #define ACQUIRE_GETADDRINFO_LOCK PyThread_acquire_lock(netdb_lock, 1); */ +/* #define RELEASE_GETADDRINFO_LOCK PyThread_release_lock(netdb_lock); */ +#else +/* #define ACQUIRE_GETADDRINFO_LOCK */ +/* #define RELEASE_GETADDRINFO_LOCK */ +#endif + + +/* Convert a string specifying a host name or one of a few symbolic + names to a numeric IP address. This usually calls gethostbyname() + to do the work; the names "" and "" are special. + Return the length (IPv4 should be 4 bytes), or negative if + an error occurred; then an exception is raised. */ + +static int +setipaddr(char *name, struct sockaddr *addr_ret, size_t addr_ret_size, int af) +{ + struct addrinfo hints, *res; + int error; + int d1, d2, d3, d4; + char ch; + + memset((void *) addr_ret, '\0', sizeof(*addr_ret)); + if (name[0] == '\0') { + int siz; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + hints.ai_socktype = SOCK_DGRAM; /*dummy*/ + hints.ai_flags = AI_PASSIVE; + /* XXX Py_BEGIN_ALLOW_THREADS */ + /* XXX ACQUIRE_GETADDRINFO_LOCK */ + error = getaddrinfo(NULL, "0", &hints, &res); + /* XXX Py_END_ALLOW_THREADS */ + /* We assume that those thread-unsafe getaddrinfo() versions + *are* safe regarding their return value, ie. that a + subsequent call to getaddrinfo() does not destroy the + outcome of the first call. */ + /* XXX RELEASE_GETADDRINFO_LOCK */ + if (error) { + RPYTHON_RAISE_OSERROR(errno); /* XXX set_gaierror(error);*/ + return -1; + } + switch (res->ai_family) { + case AF_INET: + siz = 4; + break; +#ifdef ENABLE_IPV6 + case AF_INET6: + siz = 16; + break; +#endif + default: + freeaddrinfo(res); + RPyRaiseSimpleException(PyExc_socket_error, + "unsupported address family"); + return -1; + } + if (res->ai_next) { + freeaddrinfo(res); + RPyRaiseSimpleException(PyExc_socket_error, + "wildcard resolved to multiple address"); + return -1; + } + if (res->ai_addrlen < addr_ret_size) + addr_ret_size = res->ai_addrlen; + memcpy(addr_ret, res->ai_addr, addr_ret_size); + freeaddrinfo(res); + return siz; + } + if (name[0] == '<' && strcmp(name, "") == 0) { + struct sockaddr_in *sin; + if (af != AF_INET && af != AF_UNSPEC) { + RPyRaiseSimpleException(PyExc_socket_error, + "address family mismatched"); + return -1; + } + sin = (struct sockaddr_in *)addr_ret; + memset((void *) sin, '\0', sizeof(*sin)); + sin->sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(*sin); +#endif + sin->sin_addr.s_addr = INADDR_BROADCAST; + return sizeof(sin->sin_addr); + } + if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 && + 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 && + 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) { + struct sockaddr_in *sin; + sin = (struct sockaddr_in *)addr_ret; + sin->sin_addr.s_addr = htonl( + ((long) d1 << 24) | ((long) d2 << 16) | + ((long) d3 << 8) | ((long) d4 << 0)); + sin->sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_SA_LEN + sin->sin_len = sizeof(*sin); +#endif + return 4; + } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = af; + /* XXX Py_BEGIN_ALLOW_THREADS */ + /* XXX ACQUIRE_GETADDRINFO_LOCK */ + error = getaddrinfo(name, NULL, &hints, &res); +#if defined(__digital__) && defined(__unix__) + if (error == EAI_NONAME && af == AF_UNSPEC) { + /* On Tru64 V5.1, numeric-to-addr conversion fails + if no address family is given. Assume IPv4 for now.*/ + hints.ai_family = AF_INET; + error = getaddrinfo(name, NULL, &hints, &res); + } +#endif + /* XXX Py_END_ALLOW_THREADS */ + /* XXX RELEASE_GETADDRINFO_LOCK */ /* see comment in setipaddr() */ + if (error) { + RPYTHON_RAISE_OSERROR(errno); /* XXX set_gaierror(error); */ + return -1; + } + if (res->ai_addrlen < addr_ret_size) + addr_ret_size = res->ai_addrlen; + memcpy((char *) addr_ret, res->ai_addr, addr_ret_size); + freeaddrinfo(res); + switch (addr_ret->sa_family) { + case AF_INET: + return 4; +#ifdef ENABLE_IPV6 + case AF_INET6: + return 16; +#endif + default: + RPyRaiseSimpleException(PyExc_socket_error, + "unknown address family"); + return -1; + } +} + + +/* Create a string object representing an IP address. + This is always a string of the form 'dd.dd.dd.dd' (with variable + size numbers). */ + +RPyString *makeipaddr(struct sockaddr *addr, int addrlen) +{ + char buf[NI_MAXHOST]; + int error; + + error = getnameinfo(addr, addrlen, buf, sizeof(buf), NULL, 0, + NI_NUMERICHOST); + if (error) { + return RPyString_FromString("socket.gaierror"); // XXX + } + return RPyString_FromString(buf); +} + +/* ____________________________________________________________________________ */ + RPyString *LL__socket_gethostname(void) { char buf[1024]; int res; res = gethostname(buf, sizeof buf - 1); if (res < 0) { - //XXX - //RPYTHON_RAISE_OSERROR(errno); - RPyRaiseSimpleException(PyExc_ValueError, + /* XXX set_error(); */ + RPyRaiseSimpleException(PyExc_socket_error, "gethostname() error"); return NULL; } @@ -117,17 +284,18 @@ return addr; } -RPyString *makeipaddr(struct sockaddr *addr) +RPyString *LL__socket_gethostbyname(RPyString *name) { - char buf[NI_MAXHOST]; - int error; - - error = getnameinfo(addr, sizeof (struct sockaddr), buf, sizeof(buf), NULL, 0, - NI_NUMERICHOST); - if (error) { - return RPyString_FromString("Error"); // XXX - } - return RPyString_FromString(buf); +#ifdef ENABLE_IPV6 + struct sockaddr_storage addrbuf; +#else + struct sockaddr_in addrbuf; +#endif + if (setipaddr(RPyString_AsString(name), (struct sockaddr *)&addrbuf, + sizeof(addrbuf), AF_INET) < 0) + return NULL; + return makeipaddr((struct sockaddr *)&addrbuf, + sizeof(struct sockaddr_in)); } RPySOCKET_ADDRINFO *LL__socket_nextaddrinfo(struct RPyOpaque_ADDRINFO *addr) @@ -145,7 +313,8 @@ RPyString *canonname = RPyString_FromString( info->ai_canonname?info->ai_canonname:""); - RPyString *ipaddr = makeipaddr(info->ai_addr); + RPyString *ipaddr = makeipaddr(info->ai_addr, + sizeof(struct sockaddr_in)); ret = ll__socket_addrinfo(info->ai_family, info->ai_socktype, 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 Oct 26 00:07:50 2005 @@ -562,6 +562,15 @@ res = f1() assert res == _socket.gethostname() + +def test_gethostbyname(): + import pypy.module._socket.rpython.exttable # for declare()/declaretype() + def does_stuff(host): + return _socket.gethostbyname(host) + f1 = compile(does_stuff, [str]) + res = f1("localhost") + assert res == _socket.gethostbyname("localhost") + def test_getaddrinfo(): import pypy.module._socket.rpython.exttable # for declare()/declaretype() from pypy.module._socket.rpython import rsocket @@ -579,4 +588,3 @@ f1 = compile(does_stuff, [str, str]) res = f1("localhost", "25") assert eval(res) == _socket.getaddrinfo("localhost", "25") - From pedronis at codespeak.net Wed Oct 26 01:49:21 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 01:49:21 +0200 (CEST) Subject: [pypy-svn] r18977 - pypy/dist/pypy/rpython/lltypesystem Message-ID: <20051025234921.873F027B5F@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 01:49:20 2005 New Revision: 18977 Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py Log: make __str__ and related more robust against recursive cases for Arrays and Functions Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Wed Oct 26 01:49:20 2005 @@ -299,7 +299,8 @@ else: return "%s { %s }" % (of._name, of._str_fields()) else: - return self.OF + return str(self.OF) + _str_fields = saferecursive(_str_fields, '...') def __str__(self): return "%s of %s " % (self.__class__.__name__, @@ -308,6 +309,7 @@ def _short_name(self): return "%s %s" % (self.__class__.__name__, self.OF._short_name(),) + _short_name = saferecursive(_short_name, '...') def _container_example(self): return _array(self, 1) @@ -332,11 +334,13 @@ def __str__(self): args = ', '.join(map(str, self.ARGS)) return "Func ( %s ) -> %s" % (args, self.RESULT) + __str__ = saferecursive(__str__, '...') def _short_name(self): args = ', '.join([ARG._short_name() for ARG in self.ARGS]) - return "Func(%s)->%s" % (args, self.RESULT._short_name) - + return "Func(%s)->%s" % (args, self.RESULT._short_name()) + _short_name = saferecursive(_short_name, '...') + def _container_example(self): def ex(*args): return self.RESULT._defl() From pedronis at codespeak.net Wed Oct 26 02:21:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 02:21:13 +0200 (CEST) Subject: [pypy-svn] r18980 - pypy/dist/pypy/annotation Message-ID: <20051026002113.D4F2227B5C@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 02:21:13 2005 New Revision: 18980 Modified: pypy/dist/pypy/annotation/unaryop.py Log: longstanding typo Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Wed Oct 26 02:21:13 2005 @@ -259,7 +259,7 @@ lst.listdef.agree(s_iterable.listdef) else: s_iter = s_iterable.iter() - self.method_append(s_iter.next()) + lst.method_append(s_iter.next()) def method_reverse(lst): lst.listdef.mutate() From pedronis at codespeak.net Wed Oct 26 02:53:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 02:53:59 +0200 (CEST) Subject: [pypy-svn] r18981 - in pypy/dist/pypy/translator: c/test goal Message-ID: <20051026005359.1FA5F27B5C@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 02:53:57 2005 New Revision: 18981 Modified: pypy/dist/pypy/translator/c/test/test_standalone.py pypy/dist/pypy/translator/goal/driver.py Log: force a var-size list for argv. Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Wed Oct 26 02:53:57 2005 @@ -16,6 +16,7 @@ t = Translator(entry_point) s_list_of_strings = SomeList(ListDef(None, SomeString())) + s_list_of_strings.listdef.resize() t.annotate([s_list_of_strings]) t.specialize() cbuilder = t.cbuilder(standalone=True) Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Wed Oct 26 02:53:57 2005 @@ -89,6 +89,7 @@ if standalone: ldef = listdef.ListDef(None, annmodel.SomeString()) + ldef.resize() inputtypes = [annmodel.SomeList(ldef)] self.inputtypes = inputtypes From pedronis at codespeak.net Wed Oct 26 03:11:37 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 03:11:37 +0200 (CEST) Subject: [pypy-svn] r18982 - pypy/dist/pypy/objspace/std Message-ID: <20051026011137.33C9A27B61@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 03:11:33 2005 New Revision: 18982 Modified: pypy/dist/pypy/objspace/std/objspace.py Log: forgot this Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Wed Oct 26 03:11:33 2005 @@ -348,7 +348,7 @@ return w_obj.getclass(self) def lookup(self, w_obj, name): - w_type = w_obj.getclass(self) + w_type = self.type(w_obj) return w_type.lookup(name) lookup._annspecialcase_ = 'specialize:lookup' From pedronis at codespeak.net Wed Oct 26 04:21:58 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 04:21:58 +0200 (CEST) Subject: [pypy-svn] r18983 - in pypy/dist/pypy/translator/c: . src Message-ID: <20051026022158.B207D27B5A@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 04:21:57 2005 New Revision: 18983 Modified: pypy/dist/pypy/translator/c/extfunc.py pypy/dist/pypy/translator/c/src/ll__socket.h Log: add support for isolating ll_*.h on as needed basis. Use it for ll__sockect which is broken at the moment at least on linux and Mac OS X and was causing most translationt test to fail. Now only the related extfunc tests for _socket functions fail Modified: pypy/dist/pypy/translator/c/extfunc.py ============================================================================== --- pypy/dist/pypy/translator/c/extfunc.py (original) +++ pypy/dist/pypy/translator/c/extfunc.py Wed Oct 26 04:21:57 2005 @@ -134,8 +134,21 @@ yield annotate(ll__socket.ll__socket_addrinfo, *args) def predeclare_extfuncs(db, rtyper): + modules = {} + def module_name(c_name): + frags = c_name[3:].split('_') + if frags[0] == '': + return '_' + frags[1] + else: + return frags[0] + for func, funcobj in db.externalfuncs.items(): c_name = EXTERNALS[func] + # construct a define LL_NEED_ to make it possible to isolate in-develpoment externals and headers + modname = module_name(c_name) + if modname not in modules: + modules[modname] = True + yield 'LL_NEED_%s' % modname.upper(), 1 funcptr = lltype._ptr(lltype.Ptr(lltype.typeOf(funcobj)), funcobj) # hum yield c_name, funcptr Modified: pypy/dist/pypy/translator/c/src/ll__socket.h ============================================================================== --- pypy/dist/pypy/translator/c/src/ll__socket.h (original) +++ pypy/dist/pypy/translator/c/src/ll__socket.h Wed Oct 26 04:21:57 2005 @@ -1,3 +1,4 @@ +#ifdef LL_NEED__SOCKET /* isolate */ #ifdef MS_WINDOWS /* winsock2.h has already been included before windows.h in thread_nt.h */ @@ -374,3 +375,5 @@ #endif /* !HAVE_INET_PTON */ #endif /* PYPY_NOT_MAIN_FILE */ + +#endif /* isolate */ From pedronis at codespeak.net Wed Oct 26 04:23:02 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 04:23:02 +0200 (CEST) Subject: [pypy-svn] r18984 - in pypy/dist/pypy/translator: c c/test goal Message-ID: <20051026022302.DD28C27B60@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 04:23:01 2005 New Revision: 18984 Modified: pypy/dist/pypy/translator/c/symboltable.py pypy/dist/pypy/translator/c/test/test_symboltable.py pypy/dist/pypy/translator/goal/targetrpystonex.py Log: support adt methods in debugptr too. use it with symboltable code Modified: pypy/dist/pypy/translator/c/symboltable.py ============================================================================== --- pypy/dist/pypy/translator/c/symboltable.py (original) +++ pypy/dist/pypy/translator/c/symboltable.py Wed Oct 26 04:23:01 2005 @@ -127,10 +127,15 @@ try: field_index = list(STRUCT._names).index(name) except ValueError: - raise AttributeError, name - FIELD_TYPE = STRUCT._flds[name] - offset = self._nth_offset(field_index) - return self._read(FIELD_TYPE, offset) + pass + else: + FIELD_TYPE = STRUCT._flds[name] + offset = self._nth_offset(field_index) + return self._read(FIELD_TYPE, offset) + if isinstance(self._TYPE.TO, ContainerType): + adtmeth = self._TYPE.TO._adtmeths.get(name) + if adtmeth is not None: + return adtmeth.__get__(self) raise AttributeError, name def __len__(self): Modified: pypy/dist/pypy/translator/c/test/test_symboltable.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_symboltable.py (original) +++ pypy/dist/pypy/translator/c/test/test_symboltable.py Wed Oct 26 04:23:01 2005 @@ -15,7 +15,8 @@ symtable = getsymboltable(f.__module__) debug_list = symtable[addr] - assert len(debug_list.items) == 3 - assert debug_list.items[0] == 4 - assert debug_list.items[1] == 5 - assert debug_list.items[2] == 6 + debug_items = debug_list.ll_items() + assert len(debug_items) == 3 + assert debug_items[0] == 4 + assert debug_items[1] == 5 + assert debug_items[2] == 6 Modified: pypy/dist/pypy/translator/goal/targetrpystonex.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrpystonex.py (original) +++ pypy/dist/pypy/translator/goal/targetrpystonex.py Wed Oct 26 04:23:01 2005 @@ -56,16 +56,18 @@ def compare_array_of_array(array, pylist): - assert len(array.items) == len(pylist) + items = array.ll_items() + assert len(items) == len(pylist) for i in range(len(pylist)): - x1 = array.items[i] + x1 = items[i] x2 = pylist[i] compare_array(x1, x2) def compare_array(array, pylist): - assert len(array.items) == len(pylist) + items = array.ll_items() + assert len(items) == len(pylist) for i in range(len(pylist)): - x1 = array.items[i] + x1 = items[i] x2 = pylist[i] assert x1 == x2 From pedronis at codespeak.net Wed Oct 26 04:38:21 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 04:38:21 +0200 (CEST) Subject: [pypy-svn] r18985 - pypy/dist/pypy/rpython/test Message-ID: <20051026023821.9F67627B5A@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 04:38:20 2005 New Revision: 18985 Modified: pypy/dist/pypy/rpython/test/test_llinterp.py Log: use .ll_items() consistently 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 Wed Oct 26 04:38:20 2005 @@ -186,9 +186,9 @@ def f(): return [1,2,3] res = interpret(f,[]) - assert len(res.items) == len([1,2,3]) + assert len(res.ll_items()) == len([1,2,3]) for i in range(3): - assert res.items[i] == i+1 + assert res.ll_items()[i] == i+1 def test_list_itemops(): def f(i): @@ -244,10 +244,10 @@ l.reverse() return l res = interpret(f,[]) - assert len(res.items) == len([3,2,1]) + assert len(res.ll_items()) == len([3,2,1]) print res for i in range(3): - assert res.items[i] == 3-i + assert res.ll_items()[i] == 3-i def test_list_pop(): def f(): @@ -257,7 +257,7 @@ l3 = l.pop(-1) return [l1,l2,l3] res = interpret(f,[]) - assert len(res.items) == 3 + assert len(res.ll_items()) == 3 def test_obj_obj_add(): def f(x,y): From pedronis at codespeak.net Wed Oct 26 04:38:52 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 04:38:52 +0200 (CEST) Subject: [pypy-svn] r18986 - in pypy/dist/pypy/rpython/memory: . test Message-ID: <20051026023852.7A2A927B5F@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 04:38:51 2005 New Revision: 18986 Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py pypy/dist/pypy/rpython/memory/test/test_llinterpsim.py Log: add adt meths support to the simulatoptr, use .ll_items() consistently Modified: pypy/dist/pypy/rpython/memory/lltypesimulation.py ============================================================================== --- pypy/dist/pypy/rpython/memory/lltypesimulation.py (original) +++ pypy/dist/pypy/rpython/memory/lltypesimulation.py Wed Oct 26 04:38:51 2005 @@ -77,6 +77,10 @@ return res else: assert 0, "not implemented" + if isinstance(self._T, lltype.ContainerType): + adtmeth = self._T._adtmeths.get(field_name) + if adtmeth is not None: + return adtmeth.__get__(self) raise AttributeError, ("%r instance has no field %r" % (self._T, field_name)) 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 Wed Oct 26 04:38:51 2005 @@ -152,9 +152,10 @@ def f(): return [1,2,3] res = interpret(f,[]) - assert len(res.items) == len([1,2,3]) + items = res.ll_items() + assert len(items) == len([1,2,3]) for i in range(3): - assert res.items[i] == i+1 + assert items[i] == i+1 def test_list_itemops(): def f(i): @@ -210,10 +211,11 @@ l.reverse() return l res = interpret(f,[]) - assert len(res.items) == len([3,2,1]) + items = res.ll_items() + assert len(items) == len([3,2,1]) print res for i in range(3): - assert res.items[i] == 3-i + assert items[i] == 3-i def test_list_pop(): def f(): @@ -223,7 +225,8 @@ l3 = l.pop(-1) return [l1,l2,l3] res = interpret(f,[]) - assert len(res.items) == 3 + items = res.ll_items() + assert len(items) == 3 def test_obj_obj_add(): def f(x,y): From pedronis at codespeak.net Wed Oct 26 05:18:46 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 05:18:46 +0200 (CEST) Subject: [pypy-svn] r18987 - in pypy/dist/pypy/rpython: . test Message-ID: <20051026031846.BBC2E27B5A@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 05:18:45 2005 New Revision: 18987 Modified: pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rstr.py pypy/dist/pypy/rpython/test/test_rlist.py pypy/dist/pypy/rpython/test/test_rstr.py Log: fixed-size list separate support. Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Wed Oct 26 05:18:45 2005 @@ -1,4 +1,4 @@ -from pypy.annotation.pairtype import pairtype +from pypy.annotation.pairtype import pairtype, pair from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst @@ -25,6 +25,11 @@ # 'items' points to a C-like array in memory preceded by a 'length' header, # where each item contains a primitive value or pointer to the actual list # item. +# +# or for fixed-size lists an array is directly used: +# +# item_t list_items[] +# class __extend__(annmodel.SomeList): def rtyper_makerepr(self, rtyper): @@ -38,14 +43,18 @@ else: # cannot do the rtyper.getrepr() call immediately, for the case # of recursive structures -- i.e. if the listdef contains itself - return ListRepr(rtyper, lambda: rtyper.getrepr(listitem.s_value), - listitem) + if self.listdef.listitem.resized: + return ListRepr(rtyper, lambda: rtyper.getrepr(listitem.s_value), + listitem) + else: + return FixedSizeListRepr(rtyper, lambda: rtyper.getrepr(listitem.s_value), + listitem) def rtyper_makekey(self): return self.__class__, self.listdef.listitem -class ListRepr(Repr): +class BaseListRepr(Repr): def __init__(self, rtyper, item_repr, listitem=None): self.rtyper = rtyper @@ -63,25 +72,6 @@ def recast(self, llops, v): return llops.convertvar(v, self.item_repr, self.external_item_repr) - def _setup_repr(self): - if 'item_repr' not in self.__dict__: - self.external_item_repr, self.item_repr = externalvsinternal(self.rtyper, self._item_repr_computer()) - if isinstance(self.LIST, GcForwardReference): - ITEM = self.item_repr.lowleveltype - ITEMARRAY = GcArray(ITEM) - # XXX we might think of turning length stuff into Unsigned - self.LIST.become(GcStruct("list", ("length", Signed), - ("items", Ptr(ITEMARRAY)), - adtmeths = { - "ll_newlist": ll_newlist, - "ll_length": ll_length, - "ll_items": ll_items, - }) - ) - - def compact_repr(self): - return 'ListR %s' % (self.item_repr.compact_repr(),) - def convert_const(self, listobj): # get object from bound list method #listobj = getattr(listobj, '__self__', listobj) @@ -94,16 +84,19 @@ return self.list_cache[key] except KeyError: self.setup() - result = malloc(self.LIST, immortal=True) + n = len(listobj) + result = self.prepare_const(n) self.list_cache[key] = result - result.length = len(listobj) - result.items = malloc(self.LIST.items.TO, result.length) r_item = self.item_repr - for i in range(result.length): + items = result.ll_items() + for i in range(n): x = listobj[i] - result.items[i] = r_item.convert_const(x) + items[i] = r_item.convert_const(x) return result + def prepare_const(self, nitems): + raise NotImplementedError + def get_eqfunc(self): return inputconst(Void, self.item_repr.get_ll_eq_function()) @@ -120,16 +113,69 @@ v_lst, = hop.inputargs(self) return hop.gendirectcall(ll_list_is_true, v_lst) - 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): 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_reverse(self, hop): + v_lst, = hop.inputargs(self) + hop.exception_cannot_occur() + hop.gendirectcall(ll_reverse,v_lst) + + def make_iterator_repr(self): + return ListIteratorRepr(self) + + def ll_str(self, l): + items = l.ll_items() + length = l.ll_length() + item_repr = self.item_repr + + temp = malloc(TEMP, length) + i = 0 + while i < length: + temp[i] = item_repr.ll_str(items[i]) + i += 1 + + return rstr.ll_strconcat( + rstr.list_str_open_bracket, + rstr.ll_strconcat(rstr.ll_join(rstr.list_str_sep, + length, + temp), + rstr.list_str_close_bracket)) + +class ListRepr(BaseListRepr): + + def _setup_repr(self): + if 'item_repr' not in self.__dict__: + self.external_item_repr, self.item_repr = externalvsinternal(self.rtyper, self._item_repr_computer()) + if isinstance(self.LIST, GcForwardReference): + ITEM = self.item_repr.lowleveltype + ITEMARRAY = GcArray(ITEM) + # XXX we might think of turning length stuff into Unsigned + self.LIST.become(GcStruct("list", ("length", Signed), + ("items", Ptr(ITEMARRAY)), + adtmeths = { + "ll_newlist": ll_newlist, + "ll_length": ll_length, + "ll_items": ll_items, + }) + ) + + def compact_repr(self): + return 'ListR %s' % (self.item_repr.compact_repr(),) + + def prepare_const(self, n): + result = malloc(self.LIST, immortal=True) + result.length = n + result.items = malloc(self.LIST.items.TO, n) + return result + + 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_insert(self, hop): v_lst, v_index, v_value = hop.inputargs(self, Signed, self.item_repr) @@ -146,14 +192,9 @@ hop.gendirectcall(llfn, *args) def rtype_method_extend(self, hop): - v_lst1, v_lst2 = hop.inputargs(self, self) + v_lst1, v_lst2 = hop.inputargs(*hop.args_r) 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): if hop.has_implicit_exception(IndexError): @@ -179,36 +220,37 @@ v_res = hop.gendirectcall(llfn, v_func, *args) return self.recast(hop.llops, v_res) - def make_iterator_repr(self): - return ListIteratorRepr(self) +class FixedSizeListRepr(BaseListRepr): - def ll_str(self, l): - items = l.ll_items() - length = l.ll_length() - item_repr = self.item_repr + def _setup_repr(self): + if 'item_repr' not in self.__dict__: + self.external_item_repr, self.item_repr = externalvsinternal(self.rtyper, self._item_repr_computer()) + if isinstance(self.LIST, GcForwardReference): + ITEM = self.item_repr.lowleveltype + ITEMARRAY = GcArray(ITEM, + adtmeths = { + "ll_newlist": ll_fixed_newlist, + "ll_length": ll_fixed_length, + "ll_items": ll_fixed_items, + }) - temp = malloc(TEMP, length) - i = 0 - while i < length: - temp[i] = item_repr.ll_str(items[i]) - i += 1 + self.LIST.become(ITEMARRAY) - return rstr.ll_strconcat( - rstr.list_str_open_bracket, - rstr.ll_strconcat(rstr.ll_join(rstr.list_str_sep, - length, - temp), - rstr.list_str_close_bracket)) + def compact_repr(self): + return 'FixedSizeListR %s' % (self.item_repr.compact_repr(),) + def prepare_const(self, n): + result = malloc(self.LIST, n, immortal=True) + return result -class __extend__(pairtype(ListRepr, Repr)): +class __extend__(pairtype(BaseListRepr, Repr)): def rtype_contains((r_lst, _), hop): v_lst, v_any = hop.inputargs(r_lst, r_lst.item_repr) return hop.gendirectcall(ll_listcontains, v_lst, v_any, r_lst.get_eqfunc()) -class __extend__(pairtype(ListRepr, IntegerRepr)): +class __extend__(pairtype(BaseListRepr, IntegerRepr)): def rtype_getitem((r_lst, r_int), hop): if hop.has_implicit_exception(IndexError): @@ -239,6 +281,13 @@ hop.exception_is_here() return hop.gendirectcall(llfn, v_func, v_lst, v_index, v_item) + def rtype_mul((r_lst, r_int), hop): + cRESLIST = hop.inputconst(Void, hop.r_result.LIST) + v_lst, v_factor = hop.inputargs(r_lst, Signed) + return hop.gendirectcall(ll_mul, cRESLIST, v_lst, v_factor) + +class __extend__(pairtype(ListRepr, IntegerRepr)): + def rtype_delitem((r_lst, r_int), hop): if hop.has_implicit_exception(IndexError): spec = dum_checkidx @@ -253,16 +302,11 @@ hop.exception_is_here() return hop.gendirectcall(llfn, v_func, v_lst, v_index) - def rtype_mul((r_lst, r_int), hop): - cRESLIST = hop.inputconst(Void, hop.r_result.LIST) - v_lst, v_factor = hop.inputargs(r_lst, Signed) - return hop.gendirectcall(ll_mul, cRESLIST, v_lst, v_factor) - def rtype_inplace_mul((r_lst, r_int), hop): v_lst, v_factor = hop.inputargs(r_lst, Signed) return hop.gendirectcall(ll_inplace_mul, v_lst, v_factor) -class __extend__(pairtype(ListRepr, SliceRepr)): +class __extend__(pairtype(BaseListRepr, SliceRepr)): def rtype_getitem((r_lst, r_slic), hop): cRESLIST = hop.inputconst(Void, hop.r_result.LIST) @@ -282,11 +326,13 @@ # not implemented if r_slic == startstop_slice_repr: v_lst, v_slice, v_lst2 = hop.inputargs(r_lst, startstop_slice_repr, - r_lst) + hop.args_r[2]) hop.gendirectcall(ll_listsetslice, v_lst, v_slice, v_lst2) return raise TyperError('setitem does not support slices with %r' % (r_slic,)) +class __extend__(pairtype(ListRepr, SliceRepr)): + def rtype_delitem((r_lst, r_slic), hop): if r_slic == startonly_slice_repr: v_lst, v_start = hop.inputargs(r_lst, startonly_slice_repr) @@ -298,7 +344,7 @@ return raise TyperError('delitem does not support slices with %r' % (r_slic,)) -class __extend__(pairtype(ListRepr, ListRepr)): +class __extend__(pairtype(BaseListRepr, BaseListRepr)): def convert_from_to((r_lst1, r_lst2), v, llops): if r_lst1.listitem is None or r_lst2.listitem is None: return NotImplemented @@ -307,25 +353,40 @@ return NotImplemented return v - def rtype_add((self, _), hop): - v_lst1, v_lst2 = hop.inputargs(self, self) + def rtype_is_((r_lst1, r_lst2), hop): + if r_lst1.lowleveltype != r_lst2.lowleveltype: + # obscure logic, the is can be true only if both are None + v_lst1, v_lst2 = hop.inputargs(r_lst1, r_lst2) + return hop.gendirectcall(ll_both_none, v_lst1, v_lst2) + + return pairtype(Repr, Repr).rtype_is_(pair(r_lst1, r_lst2), hop) + + def rtype_add((r_lst1, r_lst2), hop): + v_lst1, v_lst2 = hop.inputargs(r_lst1, r_lst2) cRESLIST = hop.inputconst(Void, hop.r_result.LIST) return hop.gendirectcall(ll_concat, cRESLIST, v_lst1, v_lst2) - def rtype_inplace_add((self, _), hop): - v_lst1, v_lst2 = hop.inputargs(self, self) + def rtype_eq((r_lst1, r_lst2), hop): + assert r_lst1.item_repr == r_lst2.item_repr + v_lst1, v_lst2 = hop.inputargs(r_lst1, r_lst2) + return hop.gendirectcall(ll_listeq, v_lst1, v_lst2, r_lst1.get_eqfunc()) + + def rtype_ne((r_lst1, r_lst2), hop): + assert r_lst1.item_repr == r_lst2.item_repr + v_lst1, v_lst2 = hop.inputargs(r_lst1, r_lst2) + flag = hop.gendirectcall(ll_listeq, v_lst1, v_lst2, r_lst1.get_eqfunc()) + return hop.genop('bool_not', [flag], resulttype=Bool) + +def ll_both_none(lst1, lst2): + return not lst1 and not lst2 + +class __extend__(pairtype(ListRepr, BaseListRepr)): + + def rtype_inplace_add((r_lst1, r_lst2), hop): + v_lst1, v_lst2 = hop.inputargs(r_lst1, r_lst2) hop.gendirectcall(ll_extend, v_lst1, v_lst2) return v_lst1 - def rtype_eq((self, _), hop): - v_lst1, v_lst2 = hop.inputargs(self, self) - return hop.gendirectcall(ll_listeq, v_lst1, v_lst2, self.get_eqfunc()) - - def rtype_ne((self, _), hop): - v_lst1, v_lst2 = hop.inputargs(self, self) - flag = hop.gendirectcall(ll_listeq, v_lst1, v_lst2, self.get_eqfunc()) - return hop.genop('bool_not', [flag], resulttype=Bool) - # ____________________________________________________________ # @@ -420,7 +481,7 @@ return new_lst def ll_len(l): - return l.length + return l.ll_length() def ll_list_is_true(l): # check if a list is True, allowing for None @@ -810,6 +871,19 @@ def ll_items(l): return l.items +# fixed size versions + +def ll_fixed_newlist(LIST, length): + l = malloc(LIST, length) + return l +ll_fixed_newlist = typeMethod(ll_fixed_newlist) + +def ll_fixed_length(l): + return len(l) + +def ll_fixed_items(l): + return l + def rtype_newlist(hop): nb_args = hop.nb_args r_list = hop.r_result Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Wed Oct 26 05:18:45 2005 @@ -153,8 +153,8 @@ if hop.s_result.is_constant(): return inputconst(string_repr, hop.s_result.const) r_lst = hop.args_r[1] - from pypy.rpython.rlist import ListRepr - if not isinstance(r_lst, ListRepr): + from pypy.rpython.rlist import BaseListRepr + if not isinstance(r_lst, BaseListRepr): raise TyperError("string.join of non-list: %r" % r_lst) v_str, v_lst = hop.inputargs(string_repr, r_lst) LIST = r_lst.lowleveltype.TO 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 Wed Oct 26 05:18:45 2005 @@ -18,96 +18,143 @@ """ % (name, name) del n1, n2, name -def sample_list(): # [42, 43, 44, 45] - rlist = ListRepr(None, signed_repr) - rlist.setup() - l = ll_newlist(rlist.lowleveltype.TO, 3) - ll_setitem(l, 0, 42) - ll_setitem(l, -2, 43) - ll_setitem_nonneg(l, 2, 44) - ll_append(l, 45) - return l - -def check_list(l1, expected): - assert ll_len(l1) == len(expected) - for i, x in zip(range(len(expected)), expected): - assert ll_getitem_nonneg(l1, i) == x - -def test_rlist_basic(): - l = sample_list() - assert ll_getitem(l, -4) == 42 - assert ll_getitem_nonneg(l, 1) == 43 - assert ll_getitem(l, 2) == 44 - assert ll_getitem(l, 3) == 45 - assert ll_len(l) == 4 - check_list(l, [42, 43, 44, 45]) - -def test_rlist_set_del(): - l = sample_list() - ll_setitem(l, -1, 99) - check_list(l, [42, 43, 44, 99]) - ll_setitem_nonneg(l, 1, 77) - check_list(l, [42, 77, 44, 99]) - ll_delitem_nonneg(l, 0) - check_list(l, [77, 44, 99]) - ll_delitem(l, -2) - check_list(l, [77, 99]) - ll_delitem(l, 1) - check_list(l, [77]) - ll_delitem(l, 0) - check_list(l, []) - -def test_rlist_extend_concat(): - l = sample_list() - ll_extend(l, l) - check_list(l, [42, 43, 44, 45] * 2) - l1 = ll_concat(typeOf(l).TO, l, l) - assert l1 != l - check_list(l1, [42, 43, 44, 45] * 4) - -def test_rlist_slice(): - l = sample_list() - LIST = typeOf(l).TO - check_list(ll_listslice_startonly(LIST, l, 0), [42, 43, 44, 45]) - check_list(ll_listslice_startonly(LIST, l, 1), [43, 44, 45]) - check_list(ll_listslice_startonly(LIST, l, 2), [44, 45]) - check_list(ll_listslice_startonly(LIST, l, 3), [45]) - check_list(ll_listslice_startonly(LIST, l, 4), []) - for start in range(5): - for stop in range(start, 8): - s = ll_newslice(start, stop) - check_list(ll_listslice(LIST, l, s), [42, 43, 44, 45][start:stop]) - -def test_rlist_delslice(): - l = sample_list() - ll_listdelslice_startonly(l, 3) - check_list(l, [42, 43, 44]) - ll_listdelslice_startonly(l, 0) - check_list(l, []) - for start in range(5): - for stop in range(start, 8): - l = sample_list() - s = ll_newslice(start, stop) - ll_listdelslice(l, s) - expected = [42, 43, 44, 45] - del expected[start:stop] - check_list(l, expected) - -def test_rlist_setslice(): - n = 100 - for start in range(5): - for stop in range(start, 5): - l1 = sample_list() - l2 = sample_list() - expected = [42, 43, 44, 45] - for i in range(start, stop): - expected[i] = n - ll_setitem(l2, i, n) - n += 1 - s = ll_newslice(start, stop) - l2 = ll_listslice(typeOf(l2).TO, l2, s) - ll_listsetslice(l1, s, l2) - check_list(l1, expected) +class BaseTestListImpl: + + def check_list(self, l1, expected): + assert ll_len(l1) == len(expected) + for i, x in zip(range(len(expected)), expected): + assert ll_getitem_nonneg(l1, i) == x + + def test_rlist_basic(self): + l = self.sample_list() + assert ll_getitem(l, -4) == 42 + assert ll_getitem_nonneg(l, 1) == 43 + assert ll_getitem(l, 2) == 44 + assert ll_getitem(l, 3) == 45 + assert ll_len(l) == 4 + self.check_list(l, [42, 43, 44, 45]) + + def test_rlist_set(self): + l = self.sample_list() + ll_setitem(l, -1, 99) + self.check_list(l, [42, 43, 44, 99]) + ll_setitem_nonneg(l, 1, 77) + self.check_list(l, [42, 77, 44, 99]) + + def test_rlist_slice(self): + l = self.sample_list() + LIST = typeOf(l).TO + self.check_list(ll_listslice_startonly(LIST, l, 0), [42, 43, 44, 45]) + self.check_list(ll_listslice_startonly(LIST, l, 1), [43, 44, 45]) + self.check_list(ll_listslice_startonly(LIST, l, 2), [44, 45]) + self.check_list(ll_listslice_startonly(LIST, l, 3), [45]) + self.check_list(ll_listslice_startonly(LIST, l, 4), []) + for start in range(5): + for stop in range(start, 8): + s = ll_newslice(start, stop) + self.check_list(ll_listslice(LIST, l, s), [42, 43, 44, 45][start:stop]) + + def test_rlist_setslice(self): + n = 100 + for start in range(5): + for stop in range(start, 5): + l1 = self.sample_list() + l2 = self.sample_list() + expected = [42, 43, 44, 45] + for i in range(start, stop): + expected[i] = n + ll_setitem(l2, i, n) + n += 1 + s = ll_newslice(start, stop) + l2 = ll_listslice(typeOf(l2).TO, l2, s) + ll_listsetslice(l1, s, l2) + self.check_list(l1, expected) + +class TestListImpl(BaseTestListImpl): + + def sample_list(self): # [42, 43, 44, 45] + rlist = ListRepr(None, signed_repr) + rlist.setup() + l = ll_newlist(rlist.lowleveltype.TO, 3) + ll_setitem(l, 0, 42) + ll_setitem(l, -2, 43) + ll_setitem_nonneg(l, 2, 44) + ll_append(l, 45) + return l + + def test_rlist_del(self): + l = self.sample_list() + ll_delitem_nonneg(l, 0) + self.check_list(l, [43, 44, 45]) + ll_delitem(l, -2) + self.check_list(l, [43, 45]) + ll_delitem(l, 1) + self.check_list(l, [43]) + ll_delitem(l, 0) + self.check_list(l, []) + + def test_rlist_extend_concat(self): + l = self.sample_list() + ll_extend(l, l) + self.check_list(l, [42, 43, 44, 45] * 2) + l1 = ll_concat(typeOf(l).TO, l, l) + assert typeOf(l1) == typeOf(l) + assert l1 != l + self.check_list(l1, [42, 43, 44, 45] * 4) + + def test_rlist_delslice(self): + l = self.sample_list() + ll_listdelslice_startonly(l, 3) + self.check_list(l, [42, 43, 44]) + ll_listdelslice_startonly(l, 0) + self.check_list(l, []) + for start in range(5): + for stop in range(start, 8): + l = self.sample_list() + s = ll_newslice(start, stop) + ll_listdelslice(l, s) + expected = [42, 43, 44, 45] + del expected[start:stop] + self.check_list(l, expected) + +class TestFixedSizeListImpl(BaseTestListImpl): + + def sample_list(self): # [42, 43, 44, 45] + rlist = FixedSizeListRepr(None, signed_repr) + rlist.setup() + l = ll_fixed_newlist(rlist.lowleveltype.TO, 4) + ll_setitem(l, 0, 42) + ll_setitem(l, -3, 43) + ll_setitem_nonneg(l, 2, 44) + ll_setitem(l, 3, 45) + return l + + def test_rlist_extend_concat(self): + l = self.sample_list() + lvar = TestListImpl.sample_list(TestListImpl()) + ll_extend(lvar, l) + self.check_list(lvar, [42, 43, 44, 45] * 2) + + l1 = ll_concat(typeOf(l).TO, lvar, l) + assert typeOf(l1) == typeOf(l) + assert l1 != l + self.check_list(l1, [42, 43, 44, 45] * 3) + + l1 = ll_concat(typeOf(l).TO, l, lvar) + assert typeOf(l1) == typeOf(l) + assert l1 != l + self.check_list(l1, [42, 43, 44, 45] * 3) + + lvar1 = ll_concat(typeOf(lvar).TO, lvar, l) + assert typeOf(lvar1) == typeOf(lvar) + assert lvar1 != lvar + self.check_list(l1, [42, 43, 44, 45] * 3) + + lvar1 = ll_concat(typeOf(lvar).TO, l, lvar) + assert typeOf(lvar1) == typeOf(lvar) + assert lvar1 != lvar + self.check_list(lvar1, [42, 43, 44, 45] * 3) + # ____________________________________________________________ @@ -125,21 +172,36 @@ def dummyfn(): l = [10, 20, 30] return l[2] - rtype(dummyfn) + res = interpret(dummyfn, []) + assert res == 30 def test_append(): def dummyfn(): l = [] - l.append(5) - l.append(6) - return l[0] - rtype(dummyfn) + l.append(50) + l.append(60) + l.append(70) + l.append(80) + l.append(90) + return len(l), l[0], l[-1] + res = interpret(dummyfn, []) + assert res.item0 == 5 + assert res.item1 == 50 + assert res.item2 == 90 def test_len(): def dummyfn(): l = [5, 10] return len(l) - rtype(dummyfn) + res = interpret(dummyfn, []) + assert res == 2 + + def dummyfn(): + l = [5] + l.append(6) + return len(l) + res = interpret(dummyfn, []) + assert res == 2 def test_iterate(): def dummyfn(): @@ -147,7 +209,17 @@ for x in [1, 3, 5, 7, 9]: total += x return total - rtype(dummyfn) + res = interpret(dummyfn, []) + assert res == 25 + def dummyfn(): + total = 0 + l = [1, 3, 5, 7] + l.append(9) + for x in l: + total += x + return total + res = interpret(dummyfn, []) + assert res == 25 def test_recursive(): def dummyfn(N): @@ -156,30 +228,86 @@ l = [l] N -= 1 return len(l) - rtype(dummyfn, [int]) #.view() + res = interpret(dummyfn, [5]) + assert res == 1 + + def dummyfn(N): + l = [] + while N > 0: + l.append(l) + N -= 1 + return len(l) + res = interpret(dummyfn, [5]) + assert res == 5 + +def tolst(l): + return map(None, l.ll_items())[:l.ll_length()] def test_add(): def dummyfn(): l = [5] l += [6,7] return l + [8] - rtype(dummyfn) + res = interpret(dummyfn, []) + assert tolst(res) == [5, 6, 7, 8] + + def dummyfn(): + l = [5] + l += [6,7] + l2 = l + [8] + l2.append(9) + return l2 + res = interpret(dummyfn, []) + assert tolst(res) == [5, 6, 7, 8, 9] def test_slice(): def dummyfn(): l = [5, 6, 7, 8, 9] return l[:2], l[1:4], l[3:] - rtype(dummyfn) + res = interpret(dummyfn, []) + assert tolst(res.item0) == [5, 6] + assert tolst(res.item1) == [6, 7, 8] + assert tolst(res.item2) == [8, 9] + + def dummyfn(): + l = [5, 6, 7, 8] + l.append(9) + return l[:2], l[1:4], l[3:] + res = interpret(dummyfn, []) + assert tolst(res.item0) == [5, 6] + assert tolst(res.item1) == [6, 7, 8] + assert tolst(res.item2) == [8, 9] def test_set_del_item(): def dummyfn(): l = [5, 6, 7] l[1] = 55 l[-1] = 66 + return l + res = interpret(dummyfn, []) + assert tolst(res) == [5, 55, 66] + + def dummyfn(): + l = [] + l.append(5) + l.append(6) + l.append(7) + l[1] = 55 + l[-1] = 66 + return l + res = interpret(dummyfn, []) + assert tolst(res) == [5, 55, 66] + + def dummyfn(): + l = [5, 6, 7] + l[1] = 55 + l[-1] = 66 del l[0] del l[-1] del l[:] - rtype(dummyfn) + return len(l) + res = interpret(dummyfn, []) + assert res == 0 def test_setslice(): def dummyfn(): @@ -192,6 +320,17 @@ assert res.item2 == 8 assert res.item3 == 7 + def dummyfn(): + l = [10, 9, 8] + l.append(7) + l[:2] = [6, 5] + return l[0], l[1], l[2], l[3] + res = interpret(dummyfn, ()) + assert res.item0 == 6 + assert res.item1 == 5 + assert res.item2 == 8 + assert res.item3 == 7 + def test_insert_pop(): def dummyfn(): l = [6, 7, 8] @@ -226,6 +365,15 @@ res = interpret(dummyfn, ()) assert res == 235 + def dummyfn(): + l = [5] + l.append(3) + l.append(2) + l.reverse() + return l[0]*100 + l[1]*10 + l[2] + res = interpret(dummyfn, ()) + assert res == 235 + def test_prebuilt_list(): klist = ['a', 'd', 'z', 'k'] def dummyfn(n): @@ -237,6 +385,19 @@ res = interpret(dummyfn, [-2]) assert res == 'z' + klist = ['a', 'd', 'z'] + def mkdummyfn(): + def dummyfn(n): + klist.append('k') + return klist[n] + return dummyfn + res = interpret(mkdummyfn(), [0]) + assert res == 'a' + res = interpret(mkdummyfn(), [3]) + assert res == 'k' + res = interpret(mkdummyfn(), [-2]) + assert res == 'z' + def test_bound_list_method(): klist = [1, 2, 3] # for testing constant methods without actually mutating the constant @@ -263,7 +424,8 @@ assert res is False def dummyfn(): l1 = [1, 2] - l2 = [1, 2] + l2 = [1] + l2.append(2) return l1 is l2 res = interpret(dummyfn, []) assert res is False @@ -275,6 +437,14 @@ res = interpret(dummyfn, []) assert res is False + def dummyfn(): + l1 = None + l2 = [1] + l2.append(2) + return l1 is l2 + res = interpret(dummyfn, []) + assert res is False + def test_list_compare(): def fn(i, j, neg=False): s1 = [[1, 2, 3], [4, 5, 1], None] @@ -288,6 +458,21 @@ res = interpret(fn, [i,j,case]) assert res is fn(i, j, case) + def fn(i, j, neg=False): + s1 = [[1, 2, 3], [4, 5, 1], None] + l = [] + l.extend([1,2,3]) + s2 = [l, [4, 5, 1], [1], [1, 2], [4, 5, 1, 6], + [7, 1, 1, 8, 9, 10], None] + if neg: return s1[i] != s2[i] + return s1[i] == s2[j] + for i in range(3): + for j in range(7): + for case in False, True: + res = interpret(fn, [i,j,case]) + assert res is fn(i, j, case) + + def test_list_comparestr(): def fn(i, j, neg=False): s1 = [["hell"], ["hello", "world"]] @@ -320,6 +505,24 @@ res = interpret(fn, [i, j, case]) assert res is fn(i, j, case) + def fn(i, j, neg=False): + foo1 = Foo() + foo2 = Foo() + bar1 = Bar() + s1 = [[foo1], [foo2], [bar1]] + s2 = s1[:] + + s2[0].extend([]) + + if neg: return s1[i] != s2[i] + return s1[i] == s2[j] + for i in range(3): + for j in range(3): + for case in False, True: + res = interpret(fn, [i, j, case]) + assert res is fn(i, j, case) + + def test_list_contains(): def fn(i, neg=False): foo1 = Foo() @@ -335,6 +538,22 @@ res = interpret(fn, [i, case]) assert res is fn(i, case) + def fn(i, neg=False): + foo1 = Foo() + foo2 = Foo() + bar1 = Bar() + bar2 = Bar() + lis = [foo1, foo2, bar1] + lis.append(lis.pop()) + args = lis + [bar2] + if neg : return args[i] not in lis + return args[i] in lis + for i in range(4): + for case in False, True: + res = interpret(fn, [i, case]) + assert res is fn(i, case) + + def test_not_a_char_list_after_all(): def fn(): l = ['h', 'e', 'l', 'l', 'o'] @@ -352,12 +571,32 @@ args = lis + [bar2] return lis.index(args[i]) for i in range(4): - try: - res2 = fn(i) - res1 = interpret(fn, [i]) - assert res1 == res2 - except Exception, e: - interpret_raises(e.__class__, fn, [i]) + for varsize in False, True: + try: + res2 = fn(i) + res1 = interpret(fn, [i]) + assert res1 == res2 + except Exception, e: + interpret_raises(e.__class__, fn, [i]) + + def fn(i): + foo1 = Foo() + foo2 = Foo() + bar1 = Bar() + bar2 = Bar() + lis = [foo1, foo2, bar1] + args = lis + [bar2] + lis.append(lis.pop()) + return lis.index(args[i]) + for i in range(4): + for varsize in False, True: + try: + res2 = fn(i) + res1 = interpret(fn, [i]) + assert res1 == res2 + except Exception, e: + interpret_raises(e.__class__, fn, [i]) + def test_list_str(): def fn(): @@ -372,6 +611,22 @@ res = interpret(fn, []) assert ''.join(res.chars) == fn() + def fn(): + l = [1,2] + l.append(3) + return str(l) + + res = interpret(fn, []) + assert ''.join(res.chars) == fn() + + def fn(): + l = [1,2] + l.append(3) + return str([l]) + + res = interpret(fn, []) + assert ''.join(res.chars) == fn() + def test_list_or_None(): empty_list = [] nonempty_list = [1, 2] @@ -389,6 +644,27 @@ res = interpret(fn, [2]) assert res == 1 + + nonempty_list = [1, 2] + def fn(i): + empty_list = [1] + empty_list.pop() + nonempty_list = [] + nonempty_list.extend([1,2]) + test = [None, empty_list, nonempty_list][i] + if test: + return 1 + else: + return 0 + + res = interpret(fn, [0]) + assert res == 0 + res = interpret(fn, [1]) + assert res == 0 + res = interpret(fn, [2]) + assert res == 1 + + def test_inst_list(): def fn(): l = [None] @@ -406,6 +682,20 @@ res = interpret(fn, []) assert ''.join(res.chars) == ';[, , , , ]' + def fn(): + l = [None] * 2 + l[0] = Foo() + l[1] = Bar() + l2 = [l[1], l[0], l[0]] + l = l + [None] * 3 + i = 2 + for x in l2: + l[i] = x + i += 1 + return str(l) + res = interpret(fn, []) + assert ''.join(res.chars) == '[, , , , ]' + def test_list_slice_minusone(): def fn(i): lst = [i, i+1, i+2] @@ -414,6 +704,14 @@ res = interpret(fn, [5]) assert res == 42 + def fn(i): + lst = [i, i+1, i+2, 7] + lst.pop() + lst2 = lst[:-1] + return lst[-1] * lst2[-1] + res = interpret(fn, [5]) + assert res == 42 + def test_list_multiply(): def fn(i): lst = [i] * i @@ -476,6 +774,26 @@ res = interpret(fn, [-2]) assert res._obj.value == "oups" + def fn(i): + l = [5, 8] + l.append(3) + try: + l[i] = 99 + except IndexError: + pass + 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" + def list_is_clear(lis, idx): items = lis._obj.items._obj.items for i in range(idx, len(items)): @@ -537,6 +855,26 @@ res = interpret(fn, [6]) assert res == 100 + def fn(i): + l = [5, 8] + l.append(3) + try: + l[i] = 99 + except IndexError: + pass + 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" + def test_memoryerror(): def fn(i): lst = [0] * i 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 Oct 26 05:18:45 2005 @@ -299,6 +299,16 @@ res = interpret(fn, [i,j]) assert ''.join(res.chars) == fn(i, j) + def fn(i, j): + s1 = [ '', ',', ' and '] + s2 = [ [], ['foo'], ['bar', 'baz', 'bazz']] + s2[1].extend(['x']) + return s1[i].join(s2[j]) + for i in range(3): + for j in range(3): + res = interpret(fn, [i,j]) + assert ''.join(res.chars) == fn(i, j) + def test_parse_fmt(): assert parse_fmt_string('a') == ['a'] assert parse_fmt_string('%s') == [('s',)] From mwh at codespeak.net Wed Oct 26 11:12:22 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 11:12:22 +0200 (CEST) Subject: [pypy-svn] r18990 - pypy/dist/pypy/tool Message-ID: <20051026091222.B332727B68@code1.codespeak.net> Author: mwh Date: Wed Oct 26 11:12:21 2005 New Revision: 18990 Modified: pypy/dist/pypy/tool/importfun.py Log: checkpoint: can import-analyse all of pypy now. next: do something useful with the info :) Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Wed Oct 26 11:12:21 2005 @@ -2,6 +2,7 @@ import opcode import dis import imp +import os from sys import path, prefix """ @@ -73,6 +74,16 @@ POP_TOP +import foo.bar + +-> + +LOAD_CONST None +IMPORT_NAME foo.bar +STORE_NAME foo + +(I hate this style) + there are other forms, but i don't support them (should hit an assertion rather than silently fail). @@ -109,10 +120,15 @@ class Module(object): def __init__(self, system): self.system = system - self.imports = {} # {modname:{name:was-it-used?}} + self._imports = {} # {modname:{name:was-it-used?}} self.definitions = [] self.toplevelscope = Scope() - + def import_(self, modname): + if modname not in self._imports: + if modname not in self.system.modules: + self.system.pendingmodules[modname] = None + self._imports[modname] = {} + return self._imports[modname] def iteropcodes(codestring): n = len(codestring) @@ -165,21 +181,18 @@ if fromlist is None: # this is the 'import foo' case - if modname not in r.imports: - if modname not in r.system.modules: - r.system.pendingmodules[modname] = None - r.imports[modname] = {} + r.import_(modname) postop, postoparg = opcodes[i+1] # ban 'import foo.bar' (it's dubious style anyway, imho) - assert not '.' in modname + #assert not '.' in modname - scope.modvars[codeob.co_names[postoparg]] = modname + scope.modvars[codeob.co_names[postoparg]] = modname.split('.')[0] i += 1 elif fromlist == ('*',): - pass + r.import_(modname)['*'] = False else: # ok, this is from foo import bar path = None @@ -199,24 +212,17 @@ except ImportError: assert mods is None vars = True - if modname not in r.imports: - if modname not in r.system.modules: - r.system.pendingmodules[modname] = None - r.imports[modname] = {} - r.imports[modname][f] = False + r.import_(modname)[f] = False else: assert vars is None mods = True submod = modname + '.' + f - if submod not in r.imports: - if submod not in r.system.modules: - r.system.pendingmodules[submod] = None - r.imports[submod] = {} + r.import_(submod) op, oparg = opcodes[i] - assert op in [STORE_NAME, STORE_FAST, STORE_DEREF] - + assert op in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL] + if mods is not None: scope.modvars[codeob.co_names[oparg]] = submod else: @@ -228,22 +234,26 @@ r.definitions.append(codeob.co_names[oparg]) elif op == LOAD_ATTR: preop, preoparg = opcodes[i-1] - if preop in [LOAD_FAST, LOAD_NAME, LOAD_GLOBAL]: + if preop in [LOAD_NAME, LOAD_GLOBAL]: m = scope.mod_for_name(codeob.co_names[preoparg]) if m: - r.imports[m][codeob.co_names[oparg]] = True + r.import_(m)[codeob.co_names[oparg]] = True + elif preop in [LOAD_FAST]: + m = scope.mod_for_name(codeob.co_varnames[preoparg]) + if m: + r.import_(m)[codeob.co_names[oparg]] = True elif op in [LOAD_NAME, LOAD_GLOBAL]: name = codeob.co_names[oparg] m, a = scope.var_source(name) if m: - assert a in r.imports[m] - r.imports[m][a] = True + assert a in r.import_(m) + r.import_(m)[a] = True elif op in [LOAD_FAST]: name = codeob.co_varnames[oparg] m, a = scope.var_source(name) if m: - assert a in r.imports[m] - r.imports[m][a] = True + assert a in r.import_(m) + r.import_(m)[a] = True elif op in [MAKE_FUNCTION, MAKE_CLOSURE]: preop, preoparg = opcodes[i-1] assert preop == LOAD_CONST @@ -255,14 +265,19 @@ def process_module(dottedname, system): path = find_from_dotted_name(dottedname) - code = compile(open(path).read(), '', 'exec') + if os.path.isdir(path): + path += '/__init__.py' + code = compile(open(path, "U").read(), '', 'exec') r = Module(system) - process(r, code, r.toplevelscope, True) - - assert dottedname not in system.pendingmodules + try: + process(r, code, r.toplevelscope, True) + except ImportError, e: + print "failed!", e + else: + assert dottedname not in system.pendingmodules - system.modules[dottedname] = r + system.modules[dottedname] = r return r @@ -280,7 +295,7 @@ while system.pendingmodules: path, d = system.pendingmodules.popitem() print len(system.pendingmodules), path - if not path.startswith('pypy.'): + if not path.startswith('pypy.') or path == 'pypy._cache': continue process_module(path, system) From arigo at codespeak.net Wed Oct 26 11:42:58 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Wed, 26 Oct 2005 11:42:58 +0200 (CEST) Subject: [pypy-svn] r18991 - pypy/dist/pypy/doc Message-ID: <20051026094258.31B3B27B69@code1.codespeak.net> Author: arigo Date: Wed Oct 26 11:42:51 2005 New Revision: 18991 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Progress in Soundness and most-precise-fixpoint-ness. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Wed Oct 26 11:42:51 2005 @@ -1487,23 +1487,45 @@ rules, we introduce a third component in the state: a subset *S* of the *Rules* which stands for the currently scheduled rules. Finally, for any variable *v* we write *Rules_v* for the set of rules that have *v* -as an input or auxiliary variable. +as an input or auxiliary variable. The rule titled ``(x~y) in E`` is +called *r_x~y* for short, and it belongs to *Rules_x* and *Rules_y*. The meta-rule can be formalized as follows: we start from the initial -"meta-state" *(S,b,E)*, where *S=Rules* and *(b,E)* is the initial -state; then we apply the following meta-rule that computes a new -meta-state *(S',b',E')*:: +"meta-state" *(S_0, b_0, E_0)*, where *S_0=Rules* and *(b_0, E_0)* is +the initial state; then we apply the following meta-rule that computes a +new meta-state *(S_i+1, b_i+1, E_i+1)* from a meta-state *(S_i, b_i, +E_i)*:: + + pick a random r_i in the set of scheduled rules S_i + compute (b_i+1, E_i+1) = r_i( (b_i, E_i) ) + let S_i+1 = ( S_i - {r_i} + union Rules_v for all v for which b_i+1(v) != b_i(v) + union {r_x~y} for all (x~y) in E_i+1 but not in E_i ) + +The meta-rule is applied repeatedly, giving rise to a sequence of +meta-states *(S_0, b_0, E_0), (S_1, b_1, E_1), ... (S_n, b_n, E_n)*. +The sequence ends when *S_n* is empty, at which point annotation is +complete. The informal argument of the Termination_ paragraph shows +that this sequence is necessarily of finite length. In the +Generalization_ paragraph we have also seen that each state *(b_i+1, +E_i+1)* is equal to or more general than the previous state *(b_i, +E_i)*. + +We define an annotation state *(b,E)* to be *sound* if for all rules *r* +we have ``r( (b,E) ) = (b,E)``. We say that *(b,E)* is *degenerated* if +there is a variable *v* for which ``b(v) = Top``. We will show the +following propositions: + +1. The final state *(b_n, E_n)* is sound. + +2. If we assume that there exists (at all) a *non-degenerated* *sound* + state *(b,E)* which is at least as general as *(b_0, E_0)*, then there + is a unique minimal one among all such states, and this global minimum + is exactly *(b_n, E_n)*. - pick any r in S - compute (b',E') = r( (b,E) ) - let S' = +Proof: -The meta-rule is applied repeatedly, feeding the new meta-state back -into it, until the *S* component is empty, at which point annotation is -complete and the process stops. - - -XXX most-precise-fixpoint-ness + XXX Complexity From ericvrp at codespeak.net Wed Oct 26 11:43:24 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 26 Oct 2005 11:43:24 +0200 (CEST) Subject: [pypy-svn] r18992 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20051026094324.7EB9F27B69@code1.codespeak.net> Author: ericvrp Date: Wed Oct 26 11:43:22 2005 New Revision: 18992 Modified: pypy/dist/pypy/translator/llvm/exception.py pypy/dist/pypy/translator/llvm/gc.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/log.py pypy/dist/pypy/translator/llvm/test/test_class.py pypy/dist/pypy/translator/llvm/test/test_extfunc.py pypy/dist/pypy/translator/llvm/test/test_gc.py pypy/dist/pypy/translator/llvm/test/test_genllvm.py pypy/dist/pypy/translator/llvm/test/test_lltype.py Log: * removed (ahum) forward declaration imports (don't ask) * cleaned up some logging issues Modified: pypy/dist/pypy/translator/llvm/exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm/exception.py (original) +++ pypy/dist/pypy/translator/llvm/exception.py Wed Oct 26 11:43:22 2005 @@ -51,13 +51,10 @@ def new(exceptionpolicy=None): #factory exceptionpolicy = exceptionpolicy or 'explicit' if exceptionpolicy == 'invokeunwind': - from pypy.translator.llvm.exception import InvokeUnwindExceptionPolicy exceptionpolicy = InvokeUnwindExceptionPolicy() elif exceptionpolicy == 'explicit': - from pypy.translator.llvm.exception import ExplicitExceptionPolicy exceptionpolicy = ExplicitExceptionPolicy() elif exceptionpolicy == 'none': - from pypy.translator.llvm.exception import NoneExceptionPolicy exceptionpolicy = NoneExceptionPolicy() else: raise Exception, 'unknown exceptionpolicy: ' + str(exceptionpolicy) Modified: pypy/dist/pypy/translator/llvm/gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/gc.py (original) +++ pypy/dist/pypy/translator/llvm/gc.py Wed Oct 26 11:43:22 2005 @@ -1,8 +1,5 @@ -import py -from pypy.tool.ansi_print import ansi_log -log = py.log.Producer("llvm") -log.setconsumer("llvm", ansi_log) - +from pypy.translator.llvm.log import log +log = log.gc class GcPolicy: def __init__(self): @@ -32,13 +29,10 @@ gcpolicy = 'none' if gcpolicy == 'boehm': - from pypy.translator.llvm.gc import BoehmGcPolicy gcpolicy = BoehmGcPolicy() elif gcpolicy == 'ref': - from pypy.translator.llvm.gc import RefcountingGcPolicy gcpolicy = RefcountingGcPolicy() elif gcpolicy == 'none': - from pypy.translator.llvm.gc import NoneGcPolicy gcpolicy = NoneGcPolicy() else: raise Exception, 'unknown gcpolicy: ' + str(gcpolicy) Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Wed Oct 26 11:43:22 2005 @@ -22,10 +22,7 @@ from pypy.translator.llvm.gc import GcPolicy from pypy.translator.llvm.exception import ExceptionPolicy from pypy.translator.translator import Translator - -from pypy.tool.ansi_print import ansi_log -log = py.log.Producer("llvm") -log.setconsumer("llvm", ansi_log) +from pypy.translator.llvm.log import log function_count = {} llexterns_header = llexterns_functions = None Modified: pypy/dist/pypy/translator/llvm/log.py ============================================================================== --- pypy/dist/pypy/translator/llvm/log.py (original) +++ pypy/dist/pypy/translator/llvm/log.py Wed Oct 26 11:43:22 2005 @@ -1,4 +1,4 @@ import py -log = py.log.Producer('genllvm') -py.log.setconsumer('genllvm', None) - +from pypy.tool.ansi_print import ansi_log +log = py.log.Producer('llvm') +py.log.setconsumer('llvm', ansi_log) Modified: pypy/dist/pypy/translator/llvm/test/test_class.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_class.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_class.py Wed Oct 26 11:43:22 2005 @@ -6,8 +6,6 @@ from pypy.translator.llvm.test.runtest import compile_function from pypy.translator.llvm.test import llvmsnippet -#py.log.setconsumer("genllvm", py.log.STDOUT) - class TestClass(object): def test_classsimple(self): f = compile_function(llvmsnippet.class_simple, []) Modified: pypy/dist/pypy/translator/llvm/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_extfunc.py Wed Oct 26 11:43:22 2005 @@ -8,9 +8,6 @@ from pypy.translator.llvm.test.runtest import compile_function from pypy.rpython.rarithmetic import r_uint -py.log.setconsumer("genllvm", py.log.STDOUT) -py.log.setconsumer("genllvm database prepare", None) - def test_external_function_ll_os_dup(): def fn(): return os.dup(0) Modified: pypy/dist/pypy/translator/llvm/test/test_gc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_gc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_gc.py Wed Oct 26 11:43:22 2005 @@ -3,9 +3,6 @@ from pypy.translator.llvm.test.runtest import compile_module_function -py.log.setconsumer("genllvm", py.log.STDOUT) -py.log.setconsumer("genllvm database prepare", None) - def test_GC_malloc(): #XXX how to get to gcpolicy? #if not use_boehm_gc: Modified: pypy/dist/pypy/translator/llvm/test/test_genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_genllvm.py Wed Oct 26 11:43:22 2005 @@ -6,9 +6,6 @@ from pypy.rpython.rarithmetic import r_uint from pypy.translator.llvm.test.runtest import compile_function -py.log.setconsumer("genllvm", py.log.STDOUT) -py.log.setconsumer("genllvm database prepare", None) - def test_return1(): def simple1(): return 1 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 Wed Oct 26 11:43:22 2005 @@ -7,9 +7,6 @@ from pypy.translator.llvm import database, codewriter from pypy.rpython import rarithmetic -py.log.setconsumer("genllvm", py.log.STDOUT) -py.log.setconsumer("genllvm database prepare", None) - S = lltype.Struct("base", ('a', lltype.Signed), ('b', lltype.Signed)) def test_struct_constant1(): From mwh at codespeak.net Wed Oct 26 12:28:40 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 12:28:40 +0200 (CEST) Subject: [pypy-svn] r18994 - pypy/dist/pypy/tool Message-ID: <20051026102840.4661327B68@code1.codespeak.net> Author: mwh Date: Wed Oct 26 12:28:39 2005 New Revision: 18994 Modified: pypy/dist/pypy/tool/importfun.py Log: this might be useful now!! Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Wed Oct 26 12:28:39 2005 @@ -115,7 +115,7 @@ return self.parent.var_source(name) else: return None, None - + class Module(object): def __init__(self, system): @@ -123,6 +123,7 @@ self._imports = {} # {modname:{name:was-it-used?}} self.definitions = [] self.toplevelscope = Scope() + self.importers = [] def import_(self, modname): if modname not in self._imports: if modname not in self.system.modules: @@ -152,6 +153,7 @@ LOAD_CONST = opcode.opmap["LOAD_CONST"] LOAD_ATTR = opcode.opmap["LOAD_ATTR"] +LOAD_DEREF = opcode.opmap["LOAD_DEREF"] LOAD_FAST = opcode.opmap["LOAD_FAST"] LOAD_NAME = opcode.opmap["LOAD_NAME"] LOAD_GLOBAL = opcode.opmap["LOAD_GLOBAL"] @@ -167,10 +169,10 @@ i = 0 codeobjs = [] - + while i < len(opcodes): op, oparg = opcodes[i] - + if op == IMPORT_NAME: preop, preoparg = opcodes[i-1] assert preop == LOAD_CONST @@ -178,7 +180,7 @@ fromlist = codeob.co_consts[preoparg] modname = codeob.co_names[oparg] - + if fromlist is None: # this is the 'import foo' case r.import_(modname) @@ -186,47 +188,63 @@ postop, postoparg = opcodes[i+1] # ban 'import foo.bar' (it's dubious style anyway, imho) - + #assert not '.' in modname - + scope.modvars[codeob.co_names[postoparg]] = modname.split('.')[0] i += 1 elif fromlist == ('*',): - r.import_(modname)['*'] = False + r.import_(modname)['*'] = True else: # ok, this is from foo import bar path = None - for part in modname.split('.'): - path = [imp.find_module(part, path)[1]] -# assert '.' not in codeob.co_names[oparg] + try: + for part in modname.split('.'): + path = [imp.find_module(part, path)[1]] + except ImportError: + path = -1 i += 1 - vars = mods = None for f in fromlist: op, oparg = opcodes[i] assert op == IMPORT_FROM assert codeob.co_names[oparg] == f i += 1 + if path == -1: + i += 1 + continue + + var = mod = None + try: imp.find_module(f, path) except ImportError: - assert mods is None - vars = True + var = True r.import_(modname)[f] = False else: - assert vars is None - mods = True + mod = True submod = modname + '.' + f r.import_(submod) - + op, oparg = opcodes[i] assert op in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL] + if op == STORE_FAST: + storename = codeob.co_varnames[oparg] + elif op == STORE_DEREF: + if oparg < len(codeob.co_cellvars): + storename = codeob.co_cellvars[oparg] + else: + storename = codeob.co_freevars[oparg - len(codeob.co_cellvars)] + else: + storename = codeob.co_names[oparg] - if mods is not None: - scope.modvars[codeob.co_names[oparg]] = submod + + if mod: + scope.modvars[storename] = submod else: - scope.varsources[codeob.co_names[oparg]] = modname, f + #print 's', storename, 'm', modname, 'f', f + scope.varsources[storename] = modname, f i += 1 op, oparg = opcodes[i] assert op == POP_TOP @@ -241,7 +259,7 @@ elif preop in [LOAD_FAST]: m = scope.mod_for_name(codeob.co_varnames[preoparg]) if m: - r.import_(m)[codeob.co_names[oparg]] = True + r.import_(m)[codeob.co_names[oparg]] = True elif op in [LOAD_NAME, LOAD_GLOBAL]: name = codeob.co_names[oparg] m, a = scope.var_source(name) @@ -254,11 +272,20 @@ if m: assert a in r.import_(m) r.import_(m)[a] = True + elif op in [LOAD_DEREF]: + if oparg < len(codeob.co_cellvars): + name = codeob.co_cellvars[oparg] + else: + name = codeob.co_freevars[oparg - len(codeob.co_cellvars)] + m, a = scope.var_source(name) + if m: + assert a in r.import_(m) + r.import_(m)[a] = True elif op in [MAKE_FUNCTION, MAKE_CLOSURE]: preop, preoparg = opcodes[i-1] assert preop == LOAD_CONST codeobjs.append(codeob.co_consts[preoparg]) - + i += 1 for c in codeobjs: process(r, c, Scope(scope)) @@ -278,7 +305,7 @@ assert dottedname not in system.pendingmodules system.modules[dottedname] = r - + return r a = 1 @@ -294,10 +321,47 @@ system.pendingmodules[path] = None while system.pendingmodules: path, d = system.pendingmodules.popitem() - print len(system.pendingmodules), path + print '\r', len(system.pendingmodules), path, ' ', + sys.stdout.flush() if not path.startswith('pypy.') or path == 'pypy._cache': continue process_module(path, system) + # strip out non-pypy imports + for name, mod in system.modules.iteritems(): + for n in mod._imports.copy(): + if not n.startswith('pypy.') or n == 'pypy._cache': + del mod._imports[n] + + # record importer information +# for name, mod in system.modules.iteritems(): +# for n in mod._imports: +# system.modules[n].importers.append(name) + + unuseds = {} + + print + print '------' + + for name, mod in system.modules.iteritems(): + u = {} + for n in mod._imports: + usedany = False + for field, used in mod._imports[n].iteritems(): + if not used: + u.setdefault(n, []).append(field) + else: + usedany = True + if not usedany: + u[n] = [] + if u: + print name + for k, v in u.iteritems(): + if v: + print ' ', k, v + else: + print ' ', k, '(entirely)' + + if __name__=='__main__': main(*sys.argv[1:]) From mwh at codespeak.net Wed Oct 26 12:29:14 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 12:29:14 +0200 (CEST) Subject: [pypy-svn] r18995 - pypy/dist/pypy/translator/asm Message-ID: <20051026102914.0400B27B68@code1.codespeak.net> Author: mwh Date: Wed Oct 26 12:29:14 2005 New Revision: 18995 Modified: pypy/dist/pypy/translator/asm/genasm.py Log: first 'importfun' suggested import removal :) more (lots more :) to follow... Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 26 12:29:14 2005 @@ -1,5 +1,5 @@ import sys, os -from pypy.objspace.flow.model import traverse, Block, Variable, Constant +from pypy.objspace.flow.model import Variable, Constant #from pypy.translator.asm import infregmachine from pypy.rpython.lltypesystem.lltype import Signed from pypy.translator.asm.simulator import Machine, TranslateProgram From mwh at codespeak.net Wed Oct 26 13:14:24 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 13:14:24 +0200 (CEST) Subject: [pypy-svn] r18999 - pypy/dist/pypy/translator/asm/test Message-ID: <20051026111424.D4F0C27B58@code1.codespeak.net> Author: mwh Date: Wed Oct 26 13:14:23 2005 New Revision: 18999 Added: pypy/dist/pypy/translator/asm/test/test_model.py (contents, props changed) Log: waa, looks like i forgot to add this Added: pypy/dist/pypy/translator/asm/test/test_model.py ============================================================================== --- (empty file) +++ pypy/dist/pypy/translator/asm/test/test_model.py Wed Oct 26 13:14:23 2005 @@ -0,0 +1,80 @@ +from pypy.translator.asm.model import * +import py + +def test_simple(): + prog = [LOAD_IMMEDIATE(0, 1), + RETPYTHON(0)] + machine = Machine(prog) + assert machine.execute() == 1 + +def test_args(): + prog = [LOAD_ARGUMENT(0, 0), + RETPYTHON(0)] + machine = Machine(prog) + + for i in range(20): + assert machine.execute(i) == i + +def test_jump(): + prog = [LOAD_IMMEDIATE(0, 0), + JUMP("branch"), + LOAD_IMMEDIATE(0, 1), + Label("branch"), + RETPYTHON(0)] + + assert Machine(prog).execute() == 0 + + +def test_cond_jump(): + prog = [LOAD_ARGUMENT(0, 0), + LOAD_ARGUMENT(1, 1), + LOAD_ARGUMENT(2, 2), + JUMP_IF_FALSE(0, "branch"), + RETPYTHON(1), + Label("branch"), + RETPYTHON(2)] + + assert Machine(prog).execute(True, 1, 2) == 1 + assert Machine(prog).execute(False, 1, 2) == 2 + + prog = [LOAD_ARGUMENT(0, 0), + LOAD_ARGUMENT(1, 1), + LOAD_ARGUMENT(2, 2), + JUMP_IF_TRUE(0, "branch"), + RETPYTHON(1), + Label("branch"), + RETPYTHON(2)] + + assert Machine(prog).execute(True, 1, 2) == 2 + assert Machine(prog).execute(False, 1, 2) == 1 + +def test_llinstruction(): + prog = [LOAD_IMMEDIATE(0, 1), + LOAD_IMMEDIATE(1, 2), + LLInstruction('int_add', 0, 0, 1), + RETPYTHON(0)] + + assert Machine(prog).execute() == 3 + +def test_mov(): + prog = [LOAD_IMMEDIATE(0, 0), + LOAD_IMMEDIATE(1, 1), + MOVE(0, 1), + RETPYTHON(0)] + + assert Machine(prog).execute() == 1 + +def test_stack(): + prog = [LOAD_ARGUMENT(0, 0), + STORE_STACK(0, 0), + LOAD_STACK(1, 0), + RETPYTHON(1)] + + assert Machine(prog).execute(1) == 1 + assert Machine(prog).execute(2) == 2 + +def test_errors(): + # these should fail, it's not that relavent how... + py.test.raises(Exception, Machine([]).execute) + py.test.raises(Exception, Machine([RETPYTHON(0)]).execute) + From hpk at codespeak.net Wed Oct 26 13:16:34 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 26 Oct 2005 13:16:34 +0200 (CEST) Subject: [pypy-svn] r19000 - in pypy/extradoc/talk: . pycon2006 Message-ID: <20051026111634.3142027B5A@code1.codespeak.net> Author: hpk Date: Wed Oct 26 13:16:31 2005 New Revision: 19000 Added: pypy/extradoc/talk/pycon2006/ pypy/extradoc/talk/pycon2006/tech1-submission.txt - copied unchanged from r18999, pypy/extradoc/talk/pycon2006-submission.txt Removed: pypy/extradoc/talk/pycon2006-submission.txt Log: make a directory for upcoming three proposals From hpk at codespeak.net Wed Oct 26 13:17:21 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Wed, 26 Oct 2005 13:17:21 +0200 (CEST) Subject: [pypy-svn] r19001 - pypy/extradoc/talk/pycon2006 Message-ID: <20051026111721.1039927B5A@code1.codespeak.net> Author: hpk Date: Wed Oct 26 13:17:19 2005 New Revision: 19001 Added: pypy/extradoc/talk/pycon2006/draft-soft.txt - copied unchanged from r18999, pypy/extradoc/talk/22c3/talk-os-business.txt Log: add the CCC "social" talk verbatim for further adaptation. From mwh at codespeak.net Wed Oct 26 13:32:03 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 13:32:03 +0200 (CEST) Subject: [pypy-svn] r19003 - in pypy/dist/pypy/interpreter: . astcompiler pyparser Message-ID: <20051026113203.5246027B5A@code1.codespeak.net> Author: mwh Date: Wed Oct 26 13:31:59 2005 New Revision: 19003 Modified: 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/baseobjspace.py pypy/dist/pypy/interpreter/function.py pypy/dist/pypy/interpreter/gateway.py pypy/dist/pypy/interpreter/module.py pypy/dist/pypy/interpreter/pycode.py pypy/dist/pypy/interpreter/pycompiler.py pypy/dist/pypy/interpreter/pyframe.py pypy/dist/pypy/interpreter/pyopcode.py pypy/dist/pypy/interpreter/pyparser/error.py pypy/dist/pypy/interpreter/typedef.py Log: suggestions from 'importfun' about interpreter: remove unused imports, change some imports to import from the module that defines the name, not some other module that also imports it. Modified: pypy/dist/pypy/interpreter/astcompiler/pyassem.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pyassem.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pyassem.py Wed Oct 26 13:31:59 2005 @@ -2,7 +2,6 @@ import dis import sys -import types from pypy.interpreter.astcompiler import misc, ast from pypy.interpreter.astcompiler.consts \ Modified: pypy/dist/pypy/interpreter/astcompiler/pycodegen.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/pycodegen.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/pycodegen.py Wed Oct 26 13:31:59 2005 @@ -3,8 +3,6 @@ import marshal import struct import sys -import types -from cStringIO import StringIO from pypy.interpreter.astcompiler import ast, parse, walk, syntax from pypy.interpreter.astcompiler import pyassem, misc, future, symbols Modified: pypy/dist/pypy/interpreter/astcompiler/symbols.py ============================================================================== --- pypy/dist/pypy/interpreter/astcompiler/symbols.py (original) +++ pypy/dist/pypy/interpreter/astcompiler/symbols.py Wed Oct 26 13:31:59 2005 @@ -6,7 +6,6 @@ from pypy.interpreter.astcompiler.misc import mangle, Counter from pypy.interpreter.pyparser.error import SyntaxError from pypy.interpreter import gateway -import types import sys Modified: pypy/dist/pypy/interpreter/baseobjspace.py ============================================================================== --- pypy/dist/pypy/interpreter/baseobjspace.py (original) +++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Oct 26 13:31:59 2005 @@ -584,7 +584,6 @@ """ NOT_RPYTHON """ space = cache.space # XXX will change once we have our own compiler - from pypy.interpreter.pycode import PyCode import py source = source.lstrip() assert source.startswith('('), "incorrect header in:\n%s" % (source,) Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Wed Oct 26 13:31:59 2005 @@ -9,7 +9,6 @@ from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.eval import Code -from pypy.interpreter.gateway import NoneNotWrapped class Function(Wrappable): """A function is a code object captured with some environment: Modified: pypy/dist/pypy/interpreter/gateway.py ============================================================================== --- pypy/dist/pypy/interpreter/gateway.py (original) +++ pypy/dist/pypy/interpreter/gateway.py Wed Oct 26 13:31:59 2005 @@ -790,7 +790,6 @@ return x+y ''') """ - from pypy.interpreter.pycode import PyCode if not isinstance(source, str): source = str(py.code.Source(source).strip()) assert source.startswith("def "), "can only transform functions" Modified: pypy/dist/pypy/interpreter/module.py ============================================================================== --- pypy/dist/pypy/interpreter/module.py (original) +++ pypy/dist/pypy/interpreter/module.py Wed Oct 26 13:31:59 2005 @@ -3,7 +3,6 @@ """ from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.error import OperationError class Module(Wrappable): """A module.""" Modified: pypy/dist/pypy/interpreter/pycode.py ============================================================================== --- pypy/dist/pypy/interpreter/pycode.py (original) +++ pypy/dist/pypy/interpreter/pycode.py Wed Oct 26 13:31:59 2005 @@ -9,7 +9,6 @@ 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 # helper Modified: pypy/dist/pypy/interpreter/pycompiler.py ============================================================================== --- pypy/dist/pypy/interpreter/pycompiler.py (original) +++ pypy/dist/pypy/interpreter/pycompiler.py Wed Oct 26 13:31:59 2005 @@ -4,8 +4,6 @@ """ 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.""" Modified: pypy/dist/pypy/interpreter/pyframe.py ============================================================================== --- pypy/dist/pypy/interpreter/pyframe.py (original) +++ pypy/dist/pypy/interpreter/pyframe.py Wed Oct 26 13:31:59 2005 @@ -1,7 +1,7 @@ """ PyFrame class implementation with the interpreter main loop. """ -from pypy.interpreter import eval, baseobjspace, gateway +from pypy.interpreter import eval, baseobjspace from pypy.interpreter.miscutils import Stack, FixedStack from pypy.interpreter.error import OperationError from pypy.interpreter import pytraceback Modified: pypy/dist/pypy/interpreter/pyopcode.py ============================================================================== --- pypy/dist/pypy/interpreter/pyopcode.py (original) +++ pypy/dist/pypy/interpreter/pyopcode.py Wed Oct 26 13:31:59 2005 @@ -4,7 +4,7 @@ pyfastscope.py and pynestedscope.py. """ -from pypy.interpreter.baseobjspace import OperationError, BaseWrappable +from pypy.interpreter.error import OperationError from pypy.interpreter.baseobjspace import UnpackValueError from pypy.interpreter import gateway, function from pypy.interpreter import pyframe, pytraceback Modified: pypy/dist/pypy/interpreter/pyparser/error.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/error.py (original) +++ pypy/dist/pypy/interpreter/pyparser/error.py Wed Oct 26 13:31:59 2005 @@ -1,4 +1,3 @@ -from pypy.interpreter.error import OperationError class SyntaxError(Exception): """Base class for exceptions raised by the parser.""" Modified: pypy/dist/pypy/interpreter/typedef.py ============================================================================== --- pypy/dist/pypy/interpreter/typedef.py (original) +++ pypy/dist/pypy/interpreter/typedef.py Wed Oct 26 13:31:59 2005 @@ -2,10 +2,11 @@ """ -from pypy.interpreter.gateway import interp2app, ObjSpace, Arguments, W_Root -from pypy.interpreter.baseobjspace import BaseWrappable, Wrappable +from pypy.interpreter.gateway import interp2app +from pypy.interpreter.argument import Arguments +from pypy.interpreter.baseobjspace import \ + BaseWrappable, Wrappable, W_Root, ObjSpace from pypy.interpreter.error import OperationError -from pypy.tool.cache import Cache from pypy.tool.sourcetools import compile2 from pypy.rpython.objectmodel import instantiate From ericvrp at codespeak.net Wed Oct 26 14:12:44 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Wed, 26 Oct 2005 14:12:44 +0200 (CEST) Subject: [pypy-svn] r19004 - pypy/dist/pypy/translator/js Message-ID: <20051026121244.2BC6B27B59@code1.codespeak.net> Author: ericvrp Date: Wed Oct 26 14:12:42 2005 New Revision: 19004 Modified: pypy/dist/pypy/translator/js/arraynode.py pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/database.py pypy/dist/pypy/translator/js/exception.txt pypy/dist/pypy/translator/js/funcnode.py pypy/dist/pypy/translator/js/gc.txt pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/node.py pypy/dist/pypy/translator/js/opaquenode.py pypy/dist/pypy/translator/js/opwriter.py Log: * added ll_issubclass function * added catch exception matching Modified: pypy/dist/pypy/translator/js/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/js/arraynode.py (original) +++ pypy/dist/pypy/translator/js/arraynode.py Wed Oct 26 14:12:42 2005 @@ -64,7 +64,11 @@ def constantvalue(self): s = '"' - for c in self.value.items: + if len(self.value.items) > 0 and self.value.items[-1] == '\0': + items = self.value.items[:-1] #remove string null terminator + else: + items = self.value.items + for c in items: if ord(c) in StrArrayNode.printables: s += c else: Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Wed Oct 26 14:12:42 2005 @@ -17,7 +17,7 @@ self._skip_closeblock = flag def append(self, line, indentation_level=4): - if indentation_level: + if line and indentation_level: s = self.tabstring * indentation_level else: s = '' @@ -131,8 +131,8 @@ def neg(self, targetvar, source): self.append('%(targetvar)s = -%(source)s' % locals()) - def call(self, targetvar, functionref, argrefs, label=None, exception_exits=[]): - if exception_exits: + def call(self, targetvar, functionref, argrefs, label=None, exceptions=[], ll_issubclass=None): + if exceptions: assert label is not None self.append('try {') indentation_level = 5 @@ -143,12 +143,18 @@ args = ", ".join(argrefs) self.append('%s = %s(%s)' % (targetvar, functionref, args), indentation_level) - if exception_exits: - self.append('block = %d' % label, indentation_level) + if exceptions: + self._goto_block(label, indentation_level) self.append('} catch (e) {') - for exception in exception_exits: - self.comment('exception.target = %s' % str(exception.target), indentation_level) - self.append('block = %d' % label, indentation_level) #XXX temp + for i, exception in enumerate(exceptions): + exception_match, exception_ref, exception_target = exception + if i: + s = 'else ' + else: + s = '' + self.append('%sif (%s(e.typeptr, %s) == true) {' % (s, exception_match, exception_ref), indentation_level) + self._goto_block(exception_target, indentation_level+1) + self.append('}', indentation_level) self.append('}') def cast(self, targetvar, fromtype, fromvar, targettype): @@ -187,3 +193,6 @@ res += ''.join(['[%s]' % index for index in destindices]) res += " = %(srcvar)s" % locals() self.append(res) + + def throw(self, exc): + self.append('throw ' + exc) Modified: pypy/dist/pypy/translator/js/database.py ============================================================================== --- pypy/dist/pypy/translator/js/database.py (original) +++ pypy/dist/pypy/translator/js/database.py Wed Oct 26 14:12:42 2005 @@ -24,8 +24,7 @@ lltype.UniChar: "uint", lltype.Void: "void"} - def __init__(self, genllvm, translator): - self.genllvm = genllvm + def __init__(self, translator): self.translator = translator self.obj2node = {} self._pendingsetup = [] Modified: pypy/dist/pypy/translator/js/exception.txt ============================================================================== --- pypy/dist/pypy/translator/js/exception.txt (original) +++ pypy/dist/pypy/translator/js/exception.txt Wed Oct 26 14:12:42 2005 @@ -8,7 +8,6 @@ def new(exceptionpolicy=None): #factory exceptionpolicy = exceptionpolicy or 'invokeunwind' if exceptionpolicy == 'invokeunwind': - from pypy.translator.js.exception import InvokeUnwindExceptionPolicy exceptionpolicy = InvokeUnwindExceptionPolicy() else: raise Exception, 'unknown exceptionpolicy: ' + str(exceptionpolicy) Modified: pypy/dist/pypy/translator/js/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/js/funcnode.py (original) +++ pypy/dist/pypy/translator/js/funcnode.py Wed Oct 26 14:12:42 2005 @@ -110,14 +110,9 @@ def write_returnblock(self, codewriter, block): assert len(block.inputargs) == 1 - # #self.write_block_phi_nodes(codewriter, block) - # inputargtype = self.db.repr_arg_type(block.inputargs[0]) - # inputarg = self.db.repr_arg(block.inputargs[0]) - # codewriter.ret(inputargtype, inputarg) codewriter.ret( self.db.repr_arg(block.inputargs[0]) ) def write_exceptblock(self, codewriter, block): - #self.db.genllvm.exceptionpolicy.write_exceptblock(self, codewriter, block) - codewriter.comment('XXX TODO write_exceptblock') - codewriter.append('throw "Pypy exception"') + assert len(block.inputargs) == 2 + codewriter.throw( str(block.inputargs[1]) ) codewriter.skip_closeblock() Modified: pypy/dist/pypy/translator/js/gc.txt ============================================================================== --- pypy/dist/pypy/translator/js/gc.txt (original) +++ pypy/dist/pypy/translator/js/gc.txt Wed Oct 26 14:12:42 2005 @@ -28,13 +28,10 @@ gcpolicy = 'none' if gcpolicy == 'boehm': - from pypy.translator.js.gc import BoehmGcPolicy gcpolicy = BoehmGcPolicy() elif gcpolicy == 'ref': - from pypy.translator.js.gc import RefcountingGcPolicy gcpolicy = RefcountingGcPolicy() elif gcpolicy == 'none': - from pypy.translator.js.gc import NoneGcPolicy gcpolicy = NoneGcPolicy() else: raise Exception, 'unknown gcpolicy: ' + str(gcpolicy) Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Wed Oct 26 14:12:42 2005 @@ -25,7 +25,7 @@ class JS(object): # JS = Javascript def __init__(self, translator, function=None, debug=False): - self.db = Database(self, translator) + self.db = Database(translator) self.translator = translator LLVMNode.reset_nodename_count() #extfuncnode.ExternalFuncNode.used_external_functions = {} @@ -41,11 +41,16 @@ def write_source(self): func = self.entrypoint - ptr = getfunctionptr(self.translator, func) - c = inputconst(lltype.typeOf(ptr), ptr) - entry_point = c.value._obj + ptr = getfunctionptr(self.translator, func) + c = inputconst(lltype.typeOf(ptr), ptr) self.db.prepare_arg_value(c) + #add functions + e = self.db.translator.rtyper.getexceptiondata() + matchptr = getfunctionptr(self.db.translator, e.ll_exception_match) + matchconst = inputconst(lltype.typeOf(matchptr), matchptr) + self.db.prepare_arg_value(matchconst) + # set up all nodes self.db.setup_all() #self.entrynode = self.db.set_entrynode(entry_point) @@ -125,6 +130,7 @@ # codewriter.comment("External Function Implementation", 0) # codewriter.append(llexterns_functions) + entry_point= c.value._obj graph = self.db.obj2node[entry_point].graph startblock = graph.startblock args = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)]) Modified: pypy/dist/pypy/translator/js/node.py ============================================================================== --- pypy/dist/pypy/translator/js/node.py (original) +++ pypy/dist/pypy/translator/js/node.py Wed Oct 26 14:12:42 2005 @@ -56,9 +56,6 @@ """ Returns the constant representation for this node. """ return [] - # ______________________________________________________________________ - # entry points from genllvm - def writeglobalconstants(self, codewriter): p, c = lltype.parentlink(self.value) if p is None: Modified: pypy/dist/pypy/translator/js/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/js/opaquenode.py (original) +++ pypy/dist/pypy/translator/js/opaquenode.py Wed Oct 26 14:12:42 2005 @@ -7,8 +7,6 @@ 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 Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Wed Oct 26 14:12:42 2005 @@ -1,7 +1,7 @@ import py from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem import lltype -#from pypy.translator.js.module.extfunction import extfunctions +from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.translator.js.extfuncnode import ExternalFuncNode from pypy.translator.js.log import log log = log.opwriter @@ -204,7 +204,8 @@ targettype = self.db.repr_concretetype(op.result.concretetype) fromvar = self.db.repr_arg(op.args[0]) fromtype = self.db.repr_concretetype(op.args[0].concretetype) - self.codewriter.comment('next line=%s, from %s to %s' % (op.opname, fromtype, targettype)) + if op.opname not in ('cast_pointer',): + self.codewriter.comment('next line=%s, from %s to %s' % (op.opname, fromtype, targettype)) self.codewriter.cast(targetvar, fromtype, fromvar, targettype) same_as = cast_primitive @@ -267,18 +268,25 @@ link = self.block.exits[0] assert link.exitcase is None - targetvar = self.db.repr_arg(op.result) - #returntype = self.db.repr_arg_type(op.result) - argrefs = self.db.repr_arg_multi(op_args[1:]) - #argtypes = self.db.repr_arg_type_multi(op_args[1:]) - - none_label = self.node.blockindex[link.target] - block_label = self.node.blockindex[self.block] - #exc_label = block_label #_exception_label + targetvar = self.db.repr_arg(op.result) + argrefs = self.db.repr_arg_multi(op_args[1:]) + none_label = self.node.blockindex[link.target] + + exceptions = [] + for exit in self.block.exits[1:]: + assert issubclass(exit.exitcase, Exception) + exception_match = self.db.translator.rtyper.getexceptiondata().ll_exception_match.__name__ + exception_ref = self.db.obj2node[exit.llexitcase._obj].get_ref() + exception_target = self.node.blockindex[exit.target] + exception = (exception_match, exception_ref, exception_target) + exceptions.append(exception) - self.codewriter.call(targetvar, functionref, argrefs, none_label, self.block.exits[1:]) + self.codewriter.call(targetvar, functionref, argrefs, none_label, exceptions) return + + + e = self.db.translator.rtyper.getexceptiondata() pypy_prefix = '' #pypy_ ll_exception_match = pypy_prefix + e.ll_exception_match.__name__ From mwh at codespeak.net Wed Oct 26 20:10:24 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 20:10:24 +0200 (CEST) Subject: [pypy-svn] r19031 - pypy/dist/pypy/annotation Message-ID: <20051026181024.0722E27B58@code1.codespeak.net> Author: mwh Date: Wed Oct 26 20:10:21 2005 New Revision: 19031 Modified: pypy/dist/pypy/annotation/binaryop.py pypy/dist/pypy/annotation/bookkeeper.py pypy/dist/pypy/annotation/builtin.py pypy/dist/pypy/annotation/model.py pypy/dist/pypy/annotation/unaryop.py Log: importfun suggestions for annotation/ Modified: pypy/dist/pypy/annotation/binaryop.py ============================================================================== --- pypy/dist/pypy/annotation/binaryop.py (original) +++ pypy/dist/pypy/annotation/binaryop.py Wed Oct 26 20:10:21 2005 @@ -16,7 +16,7 @@ from pypy.annotation.model import add_knowntypedata, merge_knowntypedata from pypy.annotation.bookkeeper import getbookkeeper from pypy.annotation.classdef import isclassdef -from pypy.objspace.flow.model import Constant, Variable +from pypy.objspace.flow.model import Variable # convenience only! def immutablevalue(x): Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Wed Oct 26 20:10:21 2005 @@ -4,8 +4,8 @@ from __future__ import generators import sys -from types import FunctionType, ClassType, MethodType -from types import BuiltinMethodType, NoneType +from types import FunctionType, ClassType, NoneType +from pypy.objspace.flow.model import Constant from pypy.annotation.model import * from pypy.annotation.classdef import ClassDef, isclassdef from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Wed Oct 26 20:10:21 2005 @@ -3,7 +3,7 @@ """ import types -import sys, math, os, time +import sys, os from pypy.annotation.model import SomeInteger, SomeObject, SomeChar, SomeBool from pypy.annotation.model import SomeList, SomeString, SomeTuple, SomeSlice from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress Modified: pypy/dist/pypy/annotation/model.py ============================================================================== --- pypy/dist/pypy/annotation/model.py (original) +++ pypy/dist/pypy/annotation/model.py Wed Oct 26 20:10:21 2005 @@ -31,7 +31,6 @@ from types import BuiltinFunctionType, MethodType import pypy from pypy.annotation.pairtype import pair, extendabletype -from pypy.objspace.flow.model import Constant from pypy.tool.tls import tlsobject import inspect Modified: pypy/dist/pypy/annotation/unaryop.py ============================================================================== --- pypy/dist/pypy/annotation/unaryop.py (original) +++ pypy/dist/pypy/annotation/unaryop.py Wed Oct 26 20:10:21 2005 @@ -3,19 +3,13 @@ """ from types import FunctionType -from pypy.interpreter.argument import Arguments -from pypy.annotation.pairtype import pair -from pypy.annotation.model import SomeObject, SomeInteger, SomeBool -from pypy.annotation.model import SomeString, SomeChar, SomeList, SomeDict -from pypy.annotation.model import SomeUnicodeCodePoint -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.model import add_knowntypedata -from pypy.annotation.bookkeeper import getbookkeeper, RPythonCallsSpace +from pypy.annotation.model import \ + SomeObject, SomeInteger, SomeBool, SomeString, SomeChar, SomeList, \ + SomeDict, SomeUnicodeCodePoint, SomeTuple, SomeImpossibleValue, \ + SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \ + SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \ + unionof, set, missing_operation, add_knowntypedata +from pypy.annotation.bookkeeper import getbookkeeper from pypy.annotation.classdef import isclassdef from pypy.annotation import builtin From mwh at codespeak.net Wed Oct 26 20:10:49 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 20:10:49 +0200 (CEST) Subject: [pypy-svn] r19032 - in pypy/dist/pypy/rpython: . lltypesystem ootypesystem Message-ID: <20051026181049.6ACFF27B59@code1.codespeak.net> Author: mwh Date: Wed Oct 26 20:10:42 2005 New Revision: 19032 Modified: pypy/dist/pypy/rpython/callparse.py pypy/dist/pypy/rpython/llinterp.py pypy/dist/pypy/rpython/lltypesystem/lltype.py pypy/dist/pypy/rpython/lltypesystem/rclass.py pypy/dist/pypy/rpython/normalizecalls.py pypy/dist/pypy/rpython/ootypesystem/ootype.py pypy/dist/pypy/rpython/raddress.py pypy/dist/pypy/rpython/rbool.py pypy/dist/pypy/rpython/rbuiltin.py pypy/dist/pypy/rpython/rclass.py pypy/dist/pypy/rpython/rdict.py pypy/dist/pypy/rpython/rexternalobj.py pypy/dist/pypy/rpython/rfloat.py pypy/dist/pypy/rpython/rint.py pypy/dist/pypy/rpython/rlist.py pypy/dist/pypy/rpython/rmodel.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/rslice.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 Log: importfun suggestions for rpython/ Modified: pypy/dist/pypy/rpython/callparse.py ============================================================================== --- pypy/dist/pypy/rpython/callparse.py (original) +++ pypy/dist/pypy/rpython/callparse.py Wed Oct 26 20:10:42 2005 @@ -2,7 +2,7 @@ from pypy.interpreter.argument import Arguments, ArgErr from pypy.annotation import model as annmodel from pypy.rpython import rtuple -from pypy.rpython.rmodel import TyperError +from pypy.rpython.error import TyperError class CallPatternTooComplex(TyperError): pass Modified: pypy/dist/pypy/rpython/llinterp.py ============================================================================== --- pypy/dist/pypy/rpython/llinterp.py (original) +++ pypy/dist/pypy/rpython/llinterp.py Wed Oct 26 20:10:42 2005 @@ -1,11 +1,8 @@ -from pypy.translator.translator import Translator -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 from pypy.rpython.lltypesystem import lltype from pypy.rpython.rmodel import getfunctionptr from pypy.rpython.memory import lladdress -from pypy.rpython.objectmodel import free_non_gc_object from pypy.rpython.ootypesystem import ootype import math Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Wed Oct 26 20:10:42 2005 @@ -1,4 +1,4 @@ -import weakref, operator +import weakref import py from pypy.rpython.rarithmetic import r_uint from pypy.tool.uid import Hashable @@ -1006,17 +1006,4 @@ func._type_method = True return func -# FIXME -__all__ = ['Array', 'Bool', 'Char', 'ContainerType', 'Float', -'ForwardReference', 'FuncType', 'GC_CONTAINER', 'GcArray', 'GcForwardReference', -'GcStruct', 'Hashable', 'InvalidCast', 'LowLevelType', 'NoneType', 'OpaqueType', -'Primitive', 'Ptr', 'PyObject', 'PyObjectType', 'RuntimeTypeInfo', 'Signed', -'Struct', 'TLS', 'UniChar', 'Unsigned', 'Void', '_array', '_castdepth', -'_expose', '_func', '_opaque', '_parentable', '_ptr', '_pyobject', '_struct', -'_struct_variety', 'attachRuntimeTypeInfo', 'cast_pointer', 'cast_ptr_to_int', -'castable', 'flavored_malloc', 'frozendict', 'functionptr', -'getRuntimeTypeInfo', 'log', 'malloc', 'nullptr', 'opaqueptr', 'operator', -'parentlink', 'py', 'pyobjectptr', 'r_uint', 'runtime_type_info', 'safe_equal', -'saferecursive', 'tlsobject', 'typeOf', 'weakref', 'isCompatibleType', -'typeMethod'] Modified: pypy/dist/pypy/rpython/lltypesystem/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/lltypesystem/rclass.py (original) +++ pypy/dist/pypy/rpython/lltypesystem/rclass.py Wed Oct 26 20:10:42 2005 @@ -1,10 +1,9 @@ import sys import types from pypy.annotation.pairtype import pairtype, pair -from pypy.annotation import model as annmodel -from pypy.annotation.classdef import isclassdef from pypy.objspace.flow.model import Constant -from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning, needsgc +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, inputconst, warning from pypy.rpython.rclass import AbstractClassRepr,\ AbstractInstanceRepr,\ MissingRTypeAttribute,\ Modified: pypy/dist/pypy/rpython/normalizecalls.py ============================================================================== --- pypy/dist/pypy/rpython/normalizecalls.py (original) +++ pypy/dist/pypy/rpython/normalizecalls.py Wed Oct 26 20:10:42 2005 @@ -2,11 +2,12 @@ import types import inspect from pypy.objspace.flow.model import Variable, Constant, Block, Link -from pypy.objspace.flow.model import SpaceOperation, checkgraph +from pypy.objspace.flow.model import checkgraph 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, needsgc +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import needsgc from pypy.rpython.objectmodel import instantiate Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py ============================================================================== --- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original) +++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Wed Oct 26 20:10:42 2005 @@ -1,9 +1,3 @@ -import weakref, operator -import py -from pypy.rpython.rarithmetic import r_uint -from pypy.tool.uid import Hashable -from pypy.tool.tls import tlsobject -from types import NoneType from pypy.rpython.lltypesystem.lltype import LowLevelType, Signed, Unsigned, Float, Char from pypy.rpython.lltypesystem.lltype import Bool, Void, UniChar, typeOf, Primitive from pypy.rpython.lltypesystem.lltype import frozendict Modified: pypy/dist/pypy/rpython/raddress.py ============================================================================== --- pypy/dist/pypy/rpython/raddress.py (original) +++ pypy/dist/pypy/rpython/raddress.py Wed Oct 26 20:10:42 2005 @@ -1,8 +1,8 @@ # rtyping of memory address operations from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.memory.lladdress import address, NULL, Address -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst +from pypy.rpython.memory.lladdress import NULL, Address +from pypy.rpython.rmodel import Repr, IntegerRepr from pypy.rpython.lltypesystem import lltype class __extend__(annmodel.SomeAddress): Modified: pypy/dist/pypy/rpython/rbool.py ============================================================================== --- pypy/dist/pypy/rpython/rbool.py (original) +++ pypy/dist/pypy/rpython/rbool.py Wed Oct 26 20:10:42 2005 @@ -1,7 +1,8 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, pyobjectptr -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, BoolRepr +from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import IntegerRepr, BoolRepr from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rmodel import log Modified: pypy/dist/pypy/rpython/rbuiltin.py ============================================================================== --- pypy/dist/pypy/rpython/rbuiltin.py (original) +++ pypy/dist/pypy/rpython/rbuiltin.py Wed Oct 26 20:10:42 2005 @@ -1,14 +1,13 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel +from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem import lltype from pypy.rpython import rarithmetic, objectmodel, rstack -from pypy.rpython.rtyper import TyperError +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, IntegerRepr from pypy.rpython.rrange import rtype_builtin_range, rtype_builtin_xrange -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, Constant from pypy.rpython import rptr from pypy.rpython.robject import pyobj_repr -from pypy.rpython.rfloat import float_repr, FloatRepr -from pypy.rpython.rbool import bool_repr from pypy.rpython.rdict import rtype_r_dict from pypy.tool import sourcetools Modified: pypy/dist/pypy/rpython/rclass.py ============================================================================== --- pypy/dist/pypy/rpython/rclass.py (original) +++ pypy/dist/pypy/rpython/rclass.py Wed Oct 26 20:10:42 2005 @@ -1,10 +1,8 @@ -import sys import types -from pypy.annotation.pairtype import pairtype, pair from pypy.annotation import model as annmodel from pypy.annotation.classdef import isclassdef -from pypy.objspace.flow.model import Constant -from pypy.rpython.rmodel import Repr, TyperError, needsgc +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, needsgc def getclassrepr(rtyper, classdef): try: Modified: pypy/dist/pypy/rpython/rdict.py ============================================================================== --- pypy/dist/pypy/rpython/rdict.py (original) +++ pypy/dist/pypy/rpython/rdict.py Wed Oct 26 20:10:42 2005 @@ -4,7 +4,6 @@ from pypy.rpython.lltypesystem import lltype from pypy.rpython.rarithmetic import r_uint from pypy.rpython.objectmodel import hlinvoke -from pypy.rpython import rlist from pypy.rpython import robject from pypy.rpython import objectmodel from pypy.rpython import rmodel Modified: pypy/dist/pypy/rpython/rexternalobj.py ============================================================================== --- pypy/dist/pypy/rpython/rexternalobj.py (original) +++ pypy/dist/pypy/rpython/rexternalobj.py Wed Oct 26 20:10:42 2005 @@ -1,4 +1,3 @@ -from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem import lltype from pypy.rpython.rmodel import Repr @@ -6,7 +5,6 @@ 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 class __extend__(annmodel.SomeExternalObject): Modified: pypy/dist/pypy/rpython/rfloat.py ============================================================================== --- pypy/dist/pypy/rpython/rfloat.py (original) +++ pypy/dist/pypy/rpython/rfloat.py Wed Oct 26 20:10:42 2005 @@ -1,12 +1,12 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem.lltype import \ - Signed, Unsigned, Bool, Float, Void, Ptr, \ - PyObject, Array, Char, functionptr, FuncType, malloc -from pypy.rpython.rmodel import Repr, TyperError, FloatRepr -from pypy.rpython.rmodel import IntegerRepr, BoolRepr + Signed, Unsigned, Bool, Float, Void +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import FloatRepr +from pypy.rpython.rmodel import IntegerRepr, BoolRepr, StringRepr from pypy.rpython.robject import PyObjRepr, pyobj_repr -from pypy.rpython.rstr import STR, string_repr +from pypy.rpython.rstr import string_repr from pypy.rpython import rstr from pypy.rpython.rmodel import log @@ -81,7 +81,7 @@ def rtype_ge(_, hop): return _rtype_compare_template(hop, 'ge') -class __extend__(pairtype(rstr.StringRepr, FloatRepr)): +class __extend__(pairtype(StringRepr, FloatRepr)): def rtype_mod(_, hop): return rstr.do_stringformat(hop, [(hop.args_v[1], hop.args_r[1])]) Modified: pypy/dist/pypy/rpython/rint.py ============================================================================== --- pypy/dist/pypy/rpython/rint.py (original) +++ pypy/dist/pypy/rpython/rint.py Wed Oct 26 20:10:42 2005 @@ -4,10 +4,10 @@ from pypy.objspace.flow.objspace import op_appendices from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \ Void, Char, UniChar, GcArray, malloc, Array, pyobjectptr -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, CharRepr, \ - inputconst +from pypy.rpython.rmodel import IntegerRepr, inputconst from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rarithmetic import intmask, r_uint +from pypy.rpython.error import TyperError from pypy.rpython.rmodel import log Modified: pypy/dist/pypy/rpython/rlist.py ============================================================================== --- pypy/dist/pypy/rpython/rlist.py (original) +++ pypy/dist/pypy/rpython/rlist.py Wed Oct 26 20:10:42 2005 @@ -1,7 +1,8 @@ from pypy.annotation.pairtype import pairtype, pair from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst from pypy.rpython.rmodel import IteratorRepr, externalvsinternal from pypy.rpython.rslice import SliceRepr from pypy.rpython.rslice import startstop_slice_repr, startonly_slice_repr Modified: pypy/dist/pypy/rpython/rmodel.py ============================================================================== --- pypy/dist/pypy/rpython/rmodel.py (original) +++ pypy/dist/pypy/rpython/rmodel.py Wed Oct 26 20:10:42 2005 @@ -1,10 +1,9 @@ -from pypy.annotation.pairtype import pair, pairtype, extendabletype +from pypy.annotation.pairtype import pairtype, extendabletype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem.lltype import \ Void, Bool, Float, Signed, Char, UniChar, \ - typeOf, LowLevelType, Ptr, PyObject, \ - FuncType, functionptr, cast_ptr_to_int + typeOf, LowLevelType, Ptr, PyObject from pypy.rpython.ootypesystem import ootype from pypy.rpython.error import TyperError, MissingRTypeOperation Modified: pypy/dist/pypy/rpython/robject.py ============================================================================== --- pypy/dist/pypy/rpython/robject.py (original) +++ pypy/dist/pypy/rpython/robject.py Wed Oct 26 20:10:42 2005 @@ -1,8 +1,8 @@ -from pypy.annotation.pairtype import pair, pairtype +from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem.lltype import \ - PyObject, Ptr, Void, Bool, pyobjectptr, nullptr -from pypy.rpython.rmodel import Repr, TyperError, VoidRepr, inputconst + PyObject, Ptr, Void, pyobjectptr, nullptr +from pypy.rpython.rmodel import Repr, VoidRepr, inputconst from pypy.rpython import rclass from pypy.tool.sourcetools import func_with_new_name Modified: pypy/dist/pypy/rpython/rpbc.py ============================================================================== --- pypy/dist/pypy/rpython/rpbc.py (original) +++ pypy/dist/pypy/rpython/rpbc.py Wed Oct 26 20:10:42 2005 @@ -1,17 +1,15 @@ import types import sys -from pypy.annotation.pairtype import pairtype, pair +from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.annotation.classdef import isclassdef from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem.lltype import \ - typeOf, Void, ForwardReference, Struct, Bool, \ - Ptr, malloc, nullptr -from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning + typeOf, Void, Bool, nullptr +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, inputconst from pypy.rpython import rclass from pypy.rpython import robject -from pypy.rpython import rtuple -from pypy.tool.sourcetools import has_varargs from pypy.rpython import callparse Modified: pypy/dist/pypy/rpython/rptr.py ============================================================================== --- pypy/dist/pypy/rpython/rptr.py (original) +++ pypy/dist/pypy/rpython/rptr.py Wed Oct 26 20:10:42 2005 @@ -2,8 +2,9 @@ from pypy.annotation import model as annmodel from pypy.objspace.flow import model as flowmodel from pypy.rpython.lltypesystem.lltype import \ - Ptr, _ptr, ContainerType, Void, Signed, Bool, FuncType, typeOf -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst + Ptr, ContainerType, Void, Signed, Bool, FuncType, typeOf +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, IntegerRepr class __extend__(annmodel.SomePtr): Modified: pypy/dist/pypy/rpython/rrange.py ============================================================================== --- pypy/dist/pypy/rpython/rrange.py (original) +++ pypy/dist/pypy/rpython/rrange.py Wed Oct 26 20:10:42 2005 @@ -1,9 +1,9 @@ from pypy.annotation.pairtype import pairtype -from pypy.annotation import model as annmodel -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, IteratorRepr +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, IntegerRepr, IteratorRepr from pypy.rpython.lltypesystem.lltype import Ptr, GcStruct, Signed, malloc, Void from pypy.objspace.flow.model import Constant -from pypy.rpython.rlist import ll_newlist, dum_nocheck, dum_checkidx +from pypy.rpython.rlist import dum_nocheck, dum_checkidx # ____________________________________________________________ # Modified: pypy/dist/pypy/rpython/rslice.py ============================================================================== --- pypy/dist/pypy/rpython/rslice.py (original) +++ pypy/dist/pypy/rpython/rslice.py Wed Oct 26 20:10:42 2005 @@ -1,8 +1,7 @@ -from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr -import sys +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr from pypy.rpython.lltypesystem.lltype import \ GcStruct, Signed, Ptr, Void, malloc Modified: pypy/dist/pypy/rpython/rspecialcase.py ============================================================================== --- pypy/dist/pypy/rpython/rspecialcase.py (original) +++ pypy/dist/pypy/rpython/rspecialcase.py Wed Oct 26 20:10:42 2005 @@ -1,8 +1,5 @@ -from pypy.annotation.pairtype import pairtype -from pypy.annotation import model as annmodel -from pypy.objspace.flow.model import Constant -from pypy.rpython import rclass -from pypy.rpython.rmodel import TyperError, inputconst +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import inputconst def rtype_call_specialcase(hop): Modified: pypy/dist/pypy/rpython/rstr.py ============================================================================== --- pypy/dist/pypy/rpython/rstr.py (original) +++ pypy/dist/pypy/rpython/rstr.py Wed Oct 26 20:10:42 2005 @@ -1,9 +1,10 @@ from weakref import WeakValueDictionary from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, IteratorRepr +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import IntegerRepr, IteratorRepr from pypy.rpython.rmodel import StringRepr, CharRepr, inputconst, UniCharRepr -from pypy.rpython.rarithmetic import intmask, _hash_string +from pypy.rpython.rarithmetic import _hash_string from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.rtuple import TupleRepr from pypy.rpython import rint @@ -12,7 +13,7 @@ from pypy.rpython.rslice import minusone_slice_repr from pypy.rpython.lltypesystem.lltype import \ GcStruct, Signed, Array, Char, Ptr, malloc, \ - Bool, Void, GcArray, nullptr, typeOf, pyobjectptr + Bool, Void, GcArray, nullptr, pyobjectptr # ____________________________________________________________ Modified: pypy/dist/pypy/rpython/rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/rtuple.py (original) +++ pypy/dist/pypy/rpython/rtuple.py Wed Oct 26 20:10:42 2005 @@ -1,7 +1,8 @@ from pypy.annotation.pairtype import pairtype from pypy.annotation import model as annmodel from pypy.objspace.flow.model import Constant -from pypy.rpython.rmodel import Repr, TyperError, IntegerRepr, inputconst +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst from pypy.rpython.rmodel import IteratorRepr from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.lltypesystem.lltype import \ Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Wed Oct 26 20:10:42 2005 @@ -12,11 +12,11 @@ """ from __future__ import generators -import sys, os +import os import py from pypy.annotation.pairtype import pair from pypy.annotation import model as annmodel -from pypy.objspace.flow.model import Variable, Constant, Block, Link +from pypy.objspace.flow.model import Variable, Constant from pypy.objspace.flow.model import SpaceOperation, last_exception from pypy.rpython.lltypesystem.lltype import \ Signed, Unsigned, Float, Char, Bool, Void, \ @@ -24,11 +24,10 @@ FuncType, functionptr, typeOf, RuntimeTypeInfo, \ attachRuntimeTypeInfo, Primitive from pypy.rpython.ootypesystem import ootype -from pypy.tool.sourcetools import func_with_new_name, valid_identifier from pypy.translator.unsimplify import insert_empty_block from pypy.translator.transform import insert_stackcheck -from pypy.rpython.rmodel import Repr, inputconst -from pypy.rpython.rmodel import TyperError, BrokenReprTyperError +from pypy.rpython.error import TyperError +from pypy.rpython.rmodel import Repr, inputconst, BrokenReprTyperError from pypy.rpython.rmodel import warning from pypy.rpython.normalizecalls import perform_normalizations from pypy.rpython.annlowlevel import annotate_lowlevel_helper @@ -812,7 +811,7 @@ # and the rtyper_chooserepr() methods from pypy.rpython import robject from pypy.rpython import rint, rbool, rfloat -from pypy.rpython import rslice +from pypy.rpython import rslice, rrange from pypy.rpython import rlist, rstr, rtuple, rdict from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase from pypy.rpython import rexternalobj From mwh at codespeak.net Wed Oct 26 21:13:18 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 21:13:18 +0200 (CEST) Subject: [pypy-svn] r19037 - in pypy/dist/pypy/translator: . asm asm/ppcgen backendopt c llvm llvm/backendopt tool tool/pygame Message-ID: <20051026191318.ADF6D27B5F@code1.codespeak.net> Author: mwh Date: Wed Oct 26 21:13:08 2005 New Revision: 19037 Modified: pypy/dist/pypy/translator/annrpython.py pypy/dist/pypy/translator/asm/genasm.py pypy/dist/pypy/translator/asm/ppcgen/assembler.py pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py pypy/dist/pypy/translator/asm/simulator.py pypy/dist/pypy/translator/backendopt/all.py pypy/dist/pypy/translator/backendopt/malloc.py pypy/dist/pypy/translator/backendopt/propagate.py pypy/dist/pypy/translator/backendopt/tailrecursion.py pypy/dist/pypy/translator/c/database.py pypy/dist/pypy/translator/c/external.py pypy/dist/pypy/translator/c/gc.py pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/pyobj.py pypy/dist/pypy/translator/c/wrapper.py pypy/dist/pypy/translator/geninterplevel.py pypy/dist/pypy/translator/llvm/arraynode.py pypy/dist/pypy/translator/llvm/backendopt/exception.py pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py pypy/dist/pypy/translator/llvm/build_llvm_module.py pypy/dist/pypy/translator/llvm/codewriter.py pypy/dist/pypy/translator/llvm/database.py pypy/dist/pypy/translator/llvm/externs2ll.py pypy/dist/pypy/translator/llvm/extfuncnode.py pypy/dist/pypy/translator/llvm/funcnode.py pypy/dist/pypy/translator/llvm/genllvm.py pypy/dist/pypy/translator/llvm/opwriter.py pypy/dist/pypy/translator/llvm/structnode.py pypy/dist/pypy/translator/tool/graphpage.py pypy/dist/pypy/translator/tool/graphserver.py pypy/dist/pypy/translator/tool/pygame/graphclient.py pypy/dist/pypy/translator/transform.py pypy/dist/pypy/translator/translator.py Log: importfun vs translator/ (apart from js) haven't run all the tests yet, will do so on snake pronto. Modified: pypy/dist/pypy/translator/annrpython.py ============================================================================== --- pypy/dist/pypy/translator/annrpython.py (original) +++ pypy/dist/pypy/translator/annrpython.py Wed Oct 26 21:13:08 2005 @@ -1,12 +1,12 @@ from __future__ import generators -from types import FunctionType, ClassType +from types import ClassType from pypy.tool.ansi_print import ansi_log from pypy.annotation import model as annmodel -from pypy.annotation.model import pair +from pypy.annotation.pairtype import pair from pypy.annotation.bookkeeper import Bookkeeper from pypy.objspace.flow.model import Variable, Constant -from pypy.objspace.flow.model import SpaceOperation, FunctionGraph +from pypy.objspace.flow.model import FunctionGraph from pypy.objspace.flow.model import last_exception, checkgraph import py log = py.log.Producer("annrpython") Modified: pypy/dist/pypy/translator/asm/genasm.py ============================================================================== --- pypy/dist/pypy/translator/asm/genasm.py (original) +++ pypy/dist/pypy/translator/asm/genasm.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -import sys, os from pypy.objspace.flow.model import Variable, Constant #from pypy.translator.asm import infregmachine from pypy.rpython.lltypesystem.lltype import Signed @@ -11,6 +10,7 @@ TARGET_WIN386=2 # def determine_target(): +# import sys, os # if sys.platform == 'darwin': # if os.uname()[-1] == 'Power Macintosh': # return TARGET_PPC Modified: pypy/dist/pypy/translator/asm/ppcgen/assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/assembler.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/assembler.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -import array import os from pypy.translator.asm.ppcgen import form Modified: pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py ============================================================================== --- pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py (original) +++ pypy/dist/pypy/translator/asm/ppcgen/ppc_assembler.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -import array from pypy.translator.asm.ppcgen.ppc_form import PPCForm as Form from pypy.translator.asm.ppcgen.ppc_field import ppc_fields from pypy.translator.asm.ppcgen.assembler import Assembler Modified: pypy/dist/pypy/translator/asm/simulator.py ============================================================================== --- pypy/dist/pypy/translator/asm/simulator.py (original) +++ pypy/dist/pypy/translator/asm/simulator.py Wed Oct 26 21:13:08 2005 @@ -2,7 +2,6 @@ import autopath from pypy.rpython.llinterp import LLFrame #from pypy.translator.asm.infregmachine import Instruction -from pypy.objspace.flow.model import Constant """ Notes on the register allocation algorithm: @@ -30,7 +29,6 @@ def regmap(regperm): - import operator """answer a map IRM notation -> current FRM notation""" map={} for reg in range(1,len(regperm)): Modified: pypy/dist/pypy/translator/backendopt/all.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/all.py (original) +++ pypy/dist/pypy/translator/backendopt/all.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -from pypy.objspace.flow.model import checkgraph from pypy.translator.backendopt.removenoops import remove_same_as from pypy.translator.backendopt.inline import auto_inlining from pypy.translator.backendopt.malloc import remove_simple_mallocs Modified: pypy/dist/pypy/translator/backendopt/malloc.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/malloc.py (original) +++ pypy/dist/pypy/translator/backendopt/malloc.py Wed Oct 26 21:13:08 2005 @@ -1,5 +1,5 @@ from pypy.objspace.flow.model import Variable, Constant, Block, Link -from pypy.objspace.flow.model import SpaceOperation, traverse, checkgraph +from pypy.objspace.flow.model import SpaceOperation, traverse from pypy.tool.algo.unionfind import UnionFind from pypy.rpython.lltypesystem import lltype from pypy.translator.simplify import remove_identical_vars Modified: pypy/dist/pypy/translator/backendopt/propagate.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/propagate.py (original) +++ pypy/dist/pypy/translator/backendopt/propagate.py Wed Oct 26 21:13:08 2005 @@ -1,10 +1,10 @@ from pypy.objspace.flow.model import Block, Variable, Constant, last_exception from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph from pypy.objspace.flow.model import SpaceOperation -from pypy.rpython.lltypesystem.lltype import Void, Bool +from pypy.rpython.lltypesystem.lltype import Bool from pypy.rpython.llinterp import LLInterpreter, LLFrame from pypy.translator import simplify -from pypy.translator.backendopt.tailrecursion import get_graph +from pypy.translator.simplify import get_graph from pypy.translator.backendopt.removenoops import remove_same_as from pypy.translator.backendopt.inline import OP_WEIGHTS Modified: pypy/dist/pypy/translator/backendopt/tailrecursion.py ============================================================================== --- pypy/dist/pypy/translator/backendopt/tailrecursion.py (original) +++ pypy/dist/pypy/translator/backendopt/tailrecursion.py Wed Oct 26 21:13:08 2005 @@ -1,11 +1,5 @@ -import sys from pypy.translator.simplify import get_graph -from pypy.translator.unsimplify import copyvar, split_block -from pypy.objspace.flow.model import Variable, Constant, Block, Link -from pypy.objspace.flow.model import SpaceOperation, last_exception -from pypy.objspace.flow.model import traverse, mkentrymap, checkgraph, flatten -from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem.lltype import Bool, typeOf, FuncType, _ptr +from pypy.objspace.flow.model import mkentrymap, checkgraph # this transformation is very academical -- I had too much time Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Wed Oct 26 21:13:08 2005 @@ -1,9 +1,7 @@ -import sys from pypy.rpython.lltypesystem.lltype import \ Primitive, Ptr, typeOf, RuntimeTypeInfo, \ Struct, Array, FuncType, PyObject, Void, \ - ContainerType, pyobjectptr, OpaqueType, GcStruct -from pypy.objspace.flow.model import Constant + ContainerType, OpaqueType from pypy.translator.c.primitive import PrimitiveName, PrimitiveType from pypy.translator.c.primitive import PrimitiveErrorValue from pypy.translator.c.node import StructDefNode, ArrayDefNode Modified: pypy/dist/pypy/translator/c/external.py ============================================================================== --- pypy/dist/pypy/translator/c/external.py (original) +++ pypy/dist/pypy/translator/c/external.py Wed Oct 26 21:13:08 2005 @@ -1,7 +1,7 @@ from __future__ import generators from pypy.rpython.lltypesystem.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 +from pypy.translator.c.support import cdecl, somelettersfrom class CExternalFunctionCodeGenerator(object): Modified: pypy/dist/pypy/translator/c/gc.py ============================================================================== --- pypy/dist/pypy/translator/c/gc.py (original) +++ pypy/dist/pypy/translator/c/gc.py Wed Oct 26 21:13:08 2005 @@ -2,7 +2,7 @@ from pypy.translator.c.support import cdecl from pypy.translator.c.node import ContainerNode from pypy.rpython.lltypesystem.lltype import \ - typeOf, Ptr, PyObject, ContainerType, Array, GcArray, Struct, GcStruct, \ + typeOf, Ptr, PyObject, ContainerType, GcArray, GcStruct, \ RuntimeTypeInfo, getRuntimeTypeInfo PyObjPtr = Ptr(PyObject) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Wed Oct 26 21:13:08 2005 @@ -1,5 +1,5 @@ import autopath -import os, py +import py from pypy.translator.c.node import PyObjectNode from pypy.translator.c.database import LowLevelDatabase from pypy.translator.c.extfunc import pre_include_code_lines Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Wed Oct 26 21:13:08 2005 @@ -1,5 +1,5 @@ from __future__ import generators -import autopath, os, sys, __builtin__, marshal, zlib +import autopath, sys, __builtin__, marshal, zlib from types import FunctionType, CodeType, InstanceType, ClassType from pypy.objspace.flow.model import Variable, Constant Modified: pypy/dist/pypy/translator/c/wrapper.py ============================================================================== --- pypy/dist/pypy/translator/c/wrapper.py (original) +++ pypy/dist/pypy/translator/c/wrapper.py Wed Oct 26 21:13:08 2005 @@ -1,8 +1,7 @@ -from pypy.objspace.flow.model import Variable, Constant, SpaceOperation +from pypy.objspace.flow.model import Variable, Constant from pypy.objspace.flow.model import Block, Link, FunctionGraph, checkgraph -from pypy.annotation import model as annmodel from pypy.rpython.lltypesystem.lltype import \ - Ptr, PyObject, typeOf, Signed, Void, FuncType, functionptr + Ptr, PyObject, typeOf, Signed, FuncType, functionptr from pypy.rpython.rtyper import LowLevelOpList from pypy.rpython.rmodel import inputconst, getfunctionptr, PyObjPtr from pypy.rpython.robject import pyobj_repr Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Wed Oct 26 21:13:08 2005 @@ -44,18 +44,15 @@ """ from __future__ import generators -import autopath, os, sys, exceptions, inspect, types +import autopath, os, sys, types import cPickle as pickle, __builtin__ from copy_reg import _HEAPTYPE from pypy.objspace.flow.model import Variable, Constant, SpaceOperation -from pypy.objspace.flow.model import FunctionGraph, Block, Link -from pypy.objspace.flow.model import last_exception -from pypy.objspace.flow.model import traverse, uniqueitems, checkgraph +from pypy.objspace.flow.model import last_exception, checkgraph from pypy.interpreter.pycode import CO_VARARGS, CO_VARKEYWORDS from types import FunctionType, CodeType, ModuleType from pypy.interpreter.error import OperationError from pypy.interpreter.argument import Arguments -from pypy.rpython.rarithmetic import r_int, r_uint from pypy.translator.backendopt.ssa import SSI_to_SSA from pypy.translator.translator import Translator @@ -64,7 +61,7 @@ from pypy.tool.sourcetools import render_docstr, NiceCompile from pypy.translator.gensupp import ordered_blocks, UniqueList, builtin_base, \ - c_string, uniquemodulename, C_IDENTIFIER, NameManager + uniquemodulename, C_IDENTIFIER, NameManager # list of simplifcation passes needed by geninterp Modified: pypy/dist/pypy/translator/llvm/arraynode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/arraynode.py (original) +++ pypy/dist/pypy/translator/llvm/arraynode.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -import py from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.log import log from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode Modified: pypy/dist/pypy/translator/llvm/backendopt/exception.py ============================================================================== --- pypy/dist/pypy/translator/llvm/backendopt/exception.py (original) +++ pypy/dist/pypy/translator/llvm/backendopt/exception.py Wed Oct 26 21:13:08 2005 @@ -2,7 +2,7 @@ from pypy.objspace.flow.model import Block, Constant, Variable, Link, \ last_exception, flatten, SpaceOperation from pypy.annotation import model as annmodel -from pypy.rpython.lltypesystem.lltype import Bool, Ptr +from pypy.rpython.lltypesystem.lltype import Bool n_calls = n_calls_patched = 0 Modified: pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py ============================================================================== --- pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py (original) +++ pypy/dist/pypy/translator/llvm/backendopt/mergemallocs.py Wed Oct 26 21:13:08 2005 @@ -1,5 +1,5 @@ from pypy.objspace.flow.model import Block, flatten, SpaceOperation, Constant, Variable -from pypy.rpython.lltypesystem.lltype import Struct, GcStruct, Void, Ptr +from pypy.rpython.lltypesystem.lltype import GcStruct, Void, Ptr from pypy.translator.llvm.backendopt.support import log 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 Oct 26 21:13:08 2005 @@ -2,7 +2,7 @@ Build a Python module out of llvmfile and a Pyrex wrapper file. """ -import os, sys, inspect, re, exceptions +import os, sys from py.process import cmdexec from py import path Modified: pypy/dist/pypy/translator/llvm/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/codewriter.py (original) +++ pypy/dist/pypy/translator/llvm/codewriter.py Wed Oct 26 21:13:08 2005 @@ -1,5 +1,3 @@ -import py -from itertools import count from pypy.translator.llvm.log import log log = log.codewriter Modified: pypy/dist/pypy/translator/llvm/database.py ============================================================================== --- pypy/dist/pypy/translator/llvm/database.py (original) +++ pypy/dist/pypy/translator/llvm/database.py Wed Oct 26 21:13:08 2005 @@ -9,7 +9,6 @@ from pypy.translator.llvm.arraynode import ArrayNode, StrArrayNode, \ VoidArrayNode, ArrayTypeNode, VoidArrayTypeNode from pypy.translator.llvm.opaquenode import OpaqueNode, OpaqueTypeNode -from pypy.translator.llvm.node import ConstantLLVMNode from pypy.rpython.lltypesystem import lltype from pypy.objspace.flow.model import Constant, Variable Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Wed Oct 26 21:13:08 2005 @@ -5,8 +5,7 @@ from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython.lltypesystem import lltype -from pypy.translator.llvm.codewriter import CodeWriter, \ - DEFAULT_TAIL, DEFAULT_CCONV +from pypy.translator.llvm.codewriter import DEFAULT_CCONV from pypy.tool.udir import udir Modified: pypy/dist/pypy/translator/llvm/extfuncnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/extfuncnode.py (original) +++ pypy/dist/pypy/translator/llvm/extfuncnode.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -import py from pypy.translator.llvm.node import ConstantLLVMNode from pypy.translator.llvm.log import log log = log.extfuncnode Modified: pypy/dist/pypy/translator/llvm/funcnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/funcnode.py (original) +++ pypy/dist/pypy/translator/llvm/funcnode.py Wed Oct 26 21:13:08 2005 @@ -1,13 +1,11 @@ -import py -import sys -from pypy.objspace.flow.model import Block, Constant, Variable, Link +from pypy.objspace.flow.model import Block, Constant, Link from pypy.objspace.flow.model import flatten, mkentrymap, traverse, last_exception from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode from pypy.translator.llvm.opwriter import OpWriter from pypy.translator.llvm.log import log from pypy.translator.llvm.backendopt.removeexcmallocs import remove_exception_mallocs -from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs +#from pypy.translator.llvm.backendopt.mergemallocs import merge_mallocs from pypy.translator.unsimplify import remove_double_links log = log.funcnode Modified: pypy/dist/pypy/translator/llvm/genllvm.py ============================================================================== --- pypy/dist/pypy/translator/llvm/genllvm.py (original) +++ pypy/dist/pypy/translator/llvm/genllvm.py Wed Oct 26 21:13:08 2005 @@ -1,9 +1,4 @@ -import os import time -import types -import urllib - -import py from pypy.translator.llvm import build_llvm_module from pypy.translator.llvm.database import Database @@ -11,13 +6,11 @@ from pypy.rpython.rmodel import inputconst, getfunctionptr from pypy.rpython.lltypesystem import lltype from pypy.tool.udir import udir -from pypy.translator.llvm.codewriter import CodeWriter, \ - DEFAULT_TAIL, DEFAULT_CCONV +from pypy.translator.llvm.codewriter import CodeWriter from pypy.translator.llvm import extfuncnode from pypy.translator.llvm.module.extfunction import extdeclarations, \ extfunctions, dependencies from pypy.translator.llvm.node import LLVMNode -from pypy.translator.llvm.structnode import StructNode from pypy.translator.llvm.externs2ll import post_setup_externs, generate_llfile from pypy.translator.llvm.gc import GcPolicy from pypy.translator.llvm.exception import ExceptionPolicy Modified: pypy/dist/pypy/translator/llvm/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opwriter.py (original) +++ pypy/dist/pypy/translator/llvm/opwriter.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -import py from pypy.objspace.flow.model import Constant from pypy.rpython.lltypesystem import lltype from pypy.translator.llvm.module.extfunction import extfunctions Modified: pypy/dist/pypy/translator/llvm/structnode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/structnode.py (original) +++ pypy/dist/pypy/translator/llvm/structnode.py Wed Oct 26 21:13:08 2005 @@ -1,4 +1,3 @@ -import py from pypy.translator.llvm.log import log from pypy.translator.llvm.node import LLVMNode, ConstantLLVMNode from pypy.translator.llvm import varsize Modified: pypy/dist/pypy/translator/tool/graphpage.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphpage.py (original) +++ pypy/dist/pypy/translator/tool/graphpage.py Wed Oct 26 21:13:08 2005 @@ -1,8 +1,6 @@ import inspect, types from pypy.objspace.flow.model import traverse, Block, Link from pypy.translator.tool.make_dot import DotGen, make_dot, make_dot_graphs -from pypy.interpreter.pycode import CO_VARARGS, CO_VARKEYWORDS -from pypy.annotation import model from pypy.annotation.classdef import ClassDef from pypy.tool.uid import uid Modified: pypy/dist/pypy/translator/tool/graphserver.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphserver.py (original) +++ pypy/dist/pypy/translator/tool/graphserver.py Wed Oct 26 21:13:08 2005 @@ -92,7 +92,6 @@ def run_server_for_inprocess_client(t, options): from pypy.translator.tool import graphpage from pypy.translator.tool.pygame.graphclient import get_layout - from pypy.translator.tool.pygame.graphdisplay import GraphDisplay page = graphpage.TranslatorPage(t, options.huge) 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 Wed Oct 26 21:13:08 2005 @@ -8,7 +8,8 @@ from pypy.translator.tool.pygame.drawgraph import display_async_cmd from pypy.translator.tool.pygame.drawgraph import display_async_quit from pypy.translator.tool.pygame.drawgraph import wait_for_async_cmd -from pypy.translator.tool.graphserver import MissingPage, portutil +from pypy.translator.tool.graphserver import MissingPage +from pypy.translator.tool import port as portutil from pypy.tool.udir import udir import py Modified: pypy/dist/pypy/translator/transform.py ============================================================================== --- pypy/dist/pypy/translator/transform.py (original) +++ pypy/dist/pypy/translator/transform.py Wed Oct 26 21:13:08 2005 @@ -9,9 +9,8 @@ import types from pypy.objspace.flow.model import SpaceOperation -from pypy.objspace.flow.model import Variable, Constant, Block, Link +from pypy.objspace.flow.model import Variable, Constant, Link from pypy.objspace.flow.model import last_exception, checkgraph -from pypy.translator.annrpython import CannotSimplify from pypy.annotation import model as annmodel from pypy.annotation.specialize import MemoTable from pypy.rpython.rstack import stack_check Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Wed Oct 26 21:13:08 2005 @@ -8,9 +8,7 @@ from pypy.objspace.flow.model import * from pypy.translator.simplify import simplify_graph -from pypy.translator.gensupp import uniquemodulename from pypy.translator.tool.cbuild import make_module_from_pyxstring -from pypy.translator.tool.cbuild import make_module_from_c from pypy.objspace.flow import FlowObjSpace from pypy.tool.ansi_print import ansi_log import py @@ -136,7 +134,6 @@ """Interactive debugging helper """ if f is None: f = sys.stdout - from pypy.objspace.flow.model import Block, flatten if isinstance(x, Block): for func, graph in self.flowgraphs.items(): if x in graph.iterblocks(): From mwh at codespeak.net Wed Oct 26 21:32:33 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Wed, 26 Oct 2005 21:32:33 +0200 (CEST) Subject: [pypy-svn] r19038 - pypy/dist/pypy/translator/c Message-ID: <20051026193233.5FD6527B5F@code1.codespeak.net> Author: mwh Date: Wed Oct 26 21:32:32 2005 New Revision: 19038 Modified: pypy/dist/pypy/translator/c/pyobj.py Log: oops, this was used. Modified: pypy/dist/pypy/translator/c/pyobj.py ============================================================================== --- pypy/dist/pypy/translator/c/pyobj.py (original) +++ pypy/dist/pypy/translator/c/pyobj.py Wed Oct 26 21:32:32 2005 @@ -1,5 +1,5 @@ from __future__ import generators -import autopath, sys, __builtin__, marshal, zlib +import autopath, os, sys, __builtin__, marshal, zlib from types import FunctionType, CodeType, InstanceType, ClassType from pypy.objspace.flow.model import Variable, Constant From pedronis at codespeak.net Wed Oct 26 23:06:36 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Wed, 26 Oct 2005 23:06:36 +0200 (CEST) Subject: [pypy-svn] r19043 - pypy/dist/pypy/translator/c/test Message-ID: <20051026210636.9DFB627B5F@code1.codespeak.net> Author: pedronis Date: Wed Oct 26 23:06:34 2005 New Revision: 19043 Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: skip segfaulting test 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 Oct 26 23:06:34 2005 @@ -572,6 +572,7 @@ assert res == _socket.gethostbyname("localhost") def test_getaddrinfo(): + py.test.skip("segfaulting on linux right now") import pypy.module._socket.rpython.exttable # for declare()/declaretype() from pypy.module._socket.rpython import rsocket def does_stuff(host, port): From mwh at codespeak.net Thu Oct 27 00:03:59 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 00:03:59 +0200 (CEST) Subject: [pypy-svn] r19044 - in pypy/dist/pypy/objspace: . flow std Message-ID: <20051026220359.AE0CD27B60@code1.codespeak.net> Author: mwh Date: Thu Oct 27 00:03:54 2005 New Revision: 19044 Modified: pypy/dist/pypy/objspace/descroperation.py pypy/dist/pypy/objspace/flow/flowcontext.py pypy/dist/pypy/objspace/flow/framestate.py pypy/dist/pypy/objspace/flow/specialcase.py pypy/dist/pypy/objspace/std/dictobject.py pypy/dist/pypy/objspace/std/dictproxyobject.py pypy/dist/pypy/objspace/std/fake.py pypy/dist/pypy/objspace/std/listobject.py pypy/dist/pypy/objspace/std/longobject.py pypy/dist/pypy/objspace/std/longtype.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/register_all.py pypy/dist/pypy/objspace/std/stdtypedef.py pypy/dist/pypy/objspace/std/stringobject.py pypy/dist/pypy/objspace/std/strutil.py Log: importfun vs objspace/ objspace/std is something of a mess Modified: pypy/dist/pypy/objspace/descroperation.py ============================================================================== --- pypy/dist/pypy/objspace/descroperation.py (original) +++ pypy/dist/pypy/objspace/descroperation.py Thu Oct 27 00:03:54 2005 @@ -1,8 +1,7 @@ import operator from pypy.interpreter.error import OperationError -from pypy.interpreter.baseobjspace import ObjSpace, W_Root, BaseWrappable +from pypy.interpreter.baseobjspace import ObjSpace from pypy.interpreter.function import Function, Method -from pypy.interpreter.gateway import BuiltinCode from pypy.interpreter.argument import Arguments from pypy.tool.sourcetools import compile2, func_with_new_name Modified: pypy/dist/pypy/objspace/flow/flowcontext.py ============================================================================== --- pypy/dist/pypy/objspace/flow/flowcontext.py (original) +++ pypy/dist/pypy/objspace/flow/flowcontext.py Thu Oct 27 00:03:54 2005 @@ -246,7 +246,6 @@ return outcome, w_exc_cls, w_exc_value def build_flow(self): - from pypy.objspace.flow.objspace import UnwrapException while self.pendingblocks: block = self.pendingblocks.pop(0) frame = self.create_frame() Modified: pypy/dist/pypy/objspace/flow/framestate.py ============================================================================== --- pypy/dist/pypy/objspace/flow/framestate.py (original) +++ pypy/dist/pypy/objspace/flow/framestate.py Thu Oct 27 00:03:54 2005 @@ -1,6 +1,6 @@ from pypy.interpreter.pyframe import PyFrame, ControlFlowException from pypy.interpreter.error import OperationError -from pypy.interpreter.typedef import instantiate +from pypy.rpython.objectmodel import instantiate from pypy.objspace.flow.model import * class FrameState: Modified: pypy/dist/pypy/objspace/flow/specialcase.py ============================================================================== --- pypy/dist/pypy/objspace/flow/specialcase.py (original) +++ pypy/dist/pypy/objspace/flow/specialcase.py Thu Oct 27 00:03:54 2005 @@ -1,13 +1,8 @@ -import types, operator, sys -from pypy.interpreter import pyframe, baseobjspace -from pypy.interpreter.error import OperationError from pypy.objspace.flow.objspace import UnwrapException -from pypy.objspace.flow.model import Constant, Variable +from pypy.objspace.flow.model import Constant from pypy.objspace.flow.operation import OperationName, Arity -from pypy.interpreter import pyopcode from pypy.interpreter.gateway import ApplevelClass from pypy.tool.cache import Cache -from pypy.tool.sourcetools import NiceCompile, compile2 def sc_import(space, fn, args): w_name, w_glob, w_loc, w_frm = args.fixedunpack(4) Modified: pypy/dist/pypy/objspace/std/dictobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictobject.py (original) +++ pypy/dist/pypy/objspace/std/dictobject.py Thu Oct 27 00:03:54 2005 @@ -8,7 +8,6 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from pypy.rpython.rarithmetic import r_uint from pypy.rpython.objectmodel import r_dict Modified: pypy/dist/pypy/objspace/std/dictproxyobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictproxyobject.py (original) +++ pypy/dist/pypy/objspace/std/dictproxyobject.py Thu Oct 27 00:03:54 2005 @@ -1,5 +1,4 @@ from pypy.objspace.std.objspace import * -from pypy.interpreter.typedef import GetSetProperty def descr_get_dictproxy(space, w_obj): return W_DictProxyObject(space, w_obj.getdict()) Modified: pypy/dist/pypy/objspace/std/fake.py ============================================================================== --- pypy/dist/pypy/objspace/std/fake.py (original) +++ pypy/dist/pypy/objspace/std/fake.py Thu Oct 27 00:03:54 2005 @@ -3,8 +3,8 @@ from pypy.interpreter import eval from pypy.interpreter.function import Function, BuiltinFunction from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objspace import W_Object, StdObjSpace -from pypy.objspace.std.model import UnwrapError +from pypy.objspace.std.objspace import StdObjSpace +from pypy.objspace.std.model import W_Object, UnwrapError # this file automatically generates non-reimplementations of CPython # types that we do not yet implement in the standard object space Modified: pypy/dist/pypy/objspace/std/listobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/listobject.py (original) +++ pypy/dist/pypy/objspace/std/listobject.py Thu Oct 27 00:03:54 2005 @@ -5,7 +5,6 @@ from pypy.objspace.std import slicetype from pypy.interpreter import gateway, baseobjspace -from pypy.rpython.rarithmetic import r_uint from pypy.objspace.std.listsort import TimSort Modified: pypy/dist/pypy/objspace/std/longobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/longobject.py (original) +++ pypy/dist/pypy/objspace/std/longobject.py Thu Oct 27 00:03:54 2005 @@ -1,8 +1,8 @@ -import sys, operator +import sys from pypy.objspace.std.objspace import * from pypy.objspace.std.intobject import W_IntObject from pypy.objspace.std.noneobject import W_NoneObject -from pypy.rpython.rarithmetic import LONG_BIT, LONG_MASK, intmask, r_uint +from pypy.rpython.rarithmetic import LONG_BIT, intmask, r_uint import math Modified: pypy/dist/pypy/objspace/std/longtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/longtype.py (original) +++ pypy/dist/pypy/objspace/std/longtype.py Thu Oct 27 00:03:54 2005 @@ -1,11 +1,10 @@ from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.strutil import string_to_w_long, ParseStringError from pypy.interpreter.error import OperationError -from pypy.objspace.std.inttype import int_typedef from pypy.interpreter.gateway import NoneNotWrapped def descr__new__(space, w_longtype, w_x=0, w_base=NoneNotWrapped): - from pypy.objspace.std.longobject import W_LongObject, args_from_long + from pypy.objspace.std.longobject import W_LongObject w_value = w_x # 'x' is the keyword argument name in CPython if w_base is None: # check for easy cases Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Oct 27 00:03:54 2005 @@ -2,7 +2,7 @@ from pypy.interpreter.baseobjspace import ObjSpace, BaseWrappable from pypy.interpreter.error import OperationError, debug_print from pypy.interpreter.typedef import get_unique_interplevel_subclass -from pypy.interpreter.typedef import instantiate +from pypy.rpython.objectmodel import instantiate from pypy.interpreter.gateway import PyPyCacheDir from pypy.tool.cache import Cache from pypy.objspace.std.model import W_Object, UnwrapError @@ -10,7 +10,6 @@ from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.descroperation import DescrOperation from pypy.objspace.std import stdtypedef -import types import sys import os @@ -135,7 +134,7 @@ # generate on-the-fly class Fake: pass fake = Fake() - import pypy.lib as lib + from pypy import lib fname = os.path.join(os.path.split(lib.__file__)[0], pyname) fake.filename = fname fake.code = compile(file(fname).read(), fname, "exec") Modified: pypy/dist/pypy/objspace/std/register_all.py ============================================================================== --- pypy/dist/pypy/objspace/std/register_all.py (original) +++ pypy/dist/pypy/objspace/std/register_all.py Thu Oct 27 00:03:54 2005 @@ -12,7 +12,8 @@ If the name doesn't exist then the alternative namespace is tried for registration. """ - from pypy.objspace.std.objspace import StdObjSpace, W_ANY, W_Object + from pypy.objspace.std.objspace import StdObjSpace + from pypy.objspace.std.model import W_ANY, W_Object namespaces = [StdObjSpace.MM, StdObjSpace] if alt_ns: namespaces.insert(0, alt_ns) @@ -111,7 +112,7 @@ We try to add them in the order defined by the OP_CORRESPONDANCES table, thus favouring swapping the arguments over negating the result. """ - from pypy.objspace.std.objspace import StdObjSpace, W_ANY + from pypy.objspace.std.objspace import StdObjSpace originalentries = {} for op in OPERATORS: originalentries[op] = getattr(StdObjSpace.MM, op).signatures() Modified: pypy/dist/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/dist/pypy/objspace/std/stdtypedef.py (original) +++ pypy/dist/pypy/objspace/std/stdtypedef.py Thu Oct 27 00:03:54 2005 @@ -1,9 +1,10 @@ -from pypy.interpreter import eval, function, gateway +from pypy.interpreter import gateway, baseobjspace, argument from pypy.interpreter.error import OperationError from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.baseobjspace import SpaceCache -from pypy.objspace.std.model import MultiMethod, FailedToImplement +from pypy.objspace.std.model import MultiMethod +from pypy.objspace.std.multimethod import FailedToImplement from pypy.tool.sourcetools import compile2 __all__ = ['StdTypeDef', 'newmethod', 'gateway', @@ -246,13 +247,13 @@ def wrap_trampoline_in_gateway(func, methname, multimethod): """NOT_RPYTHON""" - unwrap_spec = [gateway.ObjSpace] + [gateway.W_Root]*multimethod.arity + unwrap_spec = [baseobjspace.ObjSpace] + [baseobjspace.W_Root]*multimethod.arity if multimethod.extras.get('varargs_w', False): unwrap_spec.append('args_w') if multimethod.extras.get('w_varargs', False): unwrap_spec.append('w_args') if multimethod.extras.get('general__args__', False): - unwrap_spec.append(gateway.Arguments) + unwrap_spec.append(argument.Arguments) return gateway.interp2app(func, app_name=methname, unwrap_spec=unwrap_spec) def slicemultimethod(space, multimethod, typedef, result, local=False): Modified: pypy/dist/pypy/objspace/std/stringobject.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringobject.py (original) +++ pypy/dist/pypy/objspace/std/stringobject.py Thu Oct 27 00:03:54 2005 @@ -2,7 +2,7 @@ from pypy.objspace.std.objspace import * from pypy.interpreter import gateway -from pypy.rpython.rarithmetic import intmask, ovfcheck, _hash_string +from pypy.rpython.rarithmetic import 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 Modified: pypy/dist/pypy/objspace/std/strutil.py ============================================================================== --- pypy/dist/pypy/objspace/std/strutil.py (original) +++ pypy/dist/pypy/objspace/std/strutil.py Thu Oct 27 00:03:54 2005 @@ -2,7 +2,7 @@ Pure Python implementation of string utilities. """ -from pypy.rpython.rarithmetic import r_uint, ovfcheck, ovfcheck_float_to_int, parts_to_float +from pypy.rpython.rarithmetic import ovfcheck, parts_to_float from pypy.interpreter.error import OperationError import math From mwh at codespeak.net Thu Oct 27 00:34:19 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 00:34:19 +0200 (CEST) Subject: [pypy-svn] r19045 - pypy/dist/pypy/tool Message-ID: <20051026223419.23EF827B5F@code1.codespeak.net> Author: mwh Date: Thu Oct 27 00:34:17 2005 New Revision: 19045 Modified: pypy/dist/pypy/tool/importfun.py Log: more fixes, features, etc Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Thu Oct 27 00:34:17 2005 @@ -191,7 +191,18 @@ #assert not '.' in modname - scope.modvars[codeob.co_names[postoparg]] = modname.split('.')[0] + assert postop in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL] + if postop == STORE_FAST: + storename = codeob.co_varnames[postoparg] + elif postop == STORE_DEREF: + if postoparg < len(codeob.co_cellvars): + storename = codeob.co_cellvars[postoparg] + else: + storename = codeob.co_freevars[postoparg - len(codeob.co_cellvars)] + else: + storename = codeob.co_names[postoparg] + + scope.modvars[storename] = modname.split('.')[0] i += 1 elif fromlist == ('*',): r.import_(modname)['*'] = True @@ -243,7 +254,6 @@ if mod: scope.modvars[storename] = submod else: - #print 's', storename, 'm', modname, 'f', f scope.varsources[storename] = modname, f i += 1 op, oparg = opcodes[i] @@ -292,10 +302,13 @@ def process_module(dottedname, system): path = find_from_dotted_name(dottedname) + ispackage = False if os.path.isdir(path): + ispackage = True path += '/__init__.py' code = compile(open(path, "U").read(), '', 'exec') r = Module(system) + r.ispackage = ispackage try: process(r, code, r.toplevelscope, True) @@ -328,10 +341,10 @@ process_module(path, system) # strip out non-pypy imports - for name, mod in system.modules.iteritems(): - for n in mod._imports.copy(): - if not n.startswith('pypy.') or n == 'pypy._cache': - del mod._imports[n] +## for name, mod in system.modules.iteritems(): +## for n in mod._imports.copy(): +## if not n.startswith('pypy.') or n == 'pypy._cache': +## del mod._imports[n] # record importer information # for name, mod in system.modules.iteritems(): @@ -343,24 +356,33 @@ print print '------' - for name, mod in system.modules.iteritems(): + for name, mod in sorted(system.modules.iteritems()): + if not 'pypy.' in name or '_cache' in name: + continue u = {} for n in mod._imports: + if n in ('autopath', '__future__'): + continue usedany = False for field, used in mod._imports[n].iteritems(): + if n in system.modules: + M = system.modules[n] + if not M.ispackage and field != '*' and field not in M.definitions: + print '***', name + print field, 'used from', n, 'but not defined there' if not used: u.setdefault(n, []).append(field) else: usedany = True if not usedany: - u[n] = [] + if n in u: + u[n].append('(i.e. entirely)') + else: + u[n] = 'entirely' if u: print name for k, v in u.iteritems(): - if v: - print ' ', k, v - else: - print ' ', k, '(entirely)' + print ' ', k, v if __name__=='__main__': From cfbolz at codespeak.net Thu Oct 27 01:13:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Oct 2005 01:13:16 +0200 (CEST) Subject: [pypy-svn] r19046 - pypy/dist/pypy/objspace/std Message-ID: <20051026231316.CEB3027B57@code1.codespeak.net> Author: cfbolz Date: Thu Oct 27 01:13:13 2005 New Revision: 19046 Modified: pypy/dist/pypy/objspace/std/dicttype.py pypy/dist/pypy/objspace/std/listtype.py pypy/dist/pypy/objspace/std/model.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/slicetype.py pypy/dist/pypy/objspace/std/stdtypedef.py pypy/dist/pypy/objspace/std/stringtype.py pypy/dist/pypy/objspace/std/unicodetype.py Log: replace MultiMethod with StdObjspaceMultiMethod Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Thu Oct 27 01:13:13 2005 @@ -2,21 +2,21 @@ 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) -dict_keys = MultiMethod('keys', 1) -dict_values = MultiMethod('values', 1) -dict_has_key = MultiMethod('has_key', 2) -dict_clear = MultiMethod('clear', 1) -dict_get = MultiMethod('get', 3, defaults=(None,)) -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, defaults=((),)) -dict_iteritems = MultiMethod('iteritems', 1) -dict_iterkeys = MultiMethod('iterkeys', 1) -dict_itervalues = MultiMethod('itervalues', 1) -dict_reversed = MultiMethod('__reversed__', 1) +dict_copy = StdObjspaceMultiMethod('copy', 1) +dict_items = StdObjspaceMultiMethod('items', 1) +dict_keys = StdObjspaceMultiMethod('keys', 1) +dict_values = StdObjspaceMultiMethod('values', 1) +dict_has_key = StdObjspaceMultiMethod('has_key', 2) +dict_clear = StdObjspaceMultiMethod('clear', 1) +dict_get = StdObjspaceMultiMethod('get', 3, defaults=(None,)) +dict_pop = StdObjspaceMultiMethod('pop', 2, w_varargs=True) +dict_popitem = StdObjspaceMultiMethod('popitem', 1) +dict_setdefault = StdObjspaceMultiMethod('setdefault', 3, defaults=(None,)) +dict_update = StdObjspaceMultiMethod('update', 2, defaults=((),)) +dict_iteritems = StdObjspaceMultiMethod('iteritems', 1) +dict_iterkeys = StdObjspaceMultiMethod('iterkeys', 1) +dict_itervalues = StdObjspaceMultiMethod('itervalues', 1) +dict_reversed = StdObjspaceMultiMethod('__reversed__', 1) def dict_reversed__ANY(space, w_dict): raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence')) Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Thu Oct 27 01:13:13 2005 @@ -3,16 +3,16 @@ from pypy.objspace.std.register_all import register_all from sys import maxint -list_append = MultiMethod('append', 2) -list_insert = MultiMethod('insert', 3) -list_extend = MultiMethod('extend', 2) -list_pop = MultiMethod('pop', 2, defaults=(-1,)) -list_remove = MultiMethod('remove', 2) -list_index = MultiMethod('index', 4, defaults=(0,maxint)) -list_count = MultiMethod('count', 2) -list_reverse = MultiMethod('reverse',1) -list_sort = MultiMethod('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse']) -list_reversed = MultiMethod('__reversed__', 1) +list_append = StdObjspaceMultiMethod('append', 2) +list_insert = StdObjspaceMultiMethod('insert', 3) +list_extend = StdObjspaceMultiMethod('extend', 2) +list_pop = StdObjspaceMultiMethod('pop', 2, defaults=(-1,)) +list_remove = StdObjspaceMultiMethod('remove', 2) +list_index = StdObjspaceMultiMethod('index', 4, defaults=(0,maxint)) +list_count = StdObjspaceMultiMethod('count', 2) +list_reverse = StdObjspaceMultiMethod('reverse',1) +list_sort = StdObjspaceMultiMethod('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse']) +list_reversed = StdObjspaceMultiMethod('__reversed__', 1) ## ### gateway is imported in the stdtypedef module ##list_reversed__ANY = gateway.applevel(''' Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Thu Oct 27 01:13:13 2005 @@ -143,7 +143,7 @@ pass -class MultiMethod(MultiMethodTable): +class StdObjspaceMultiMethod(MultiMethodTable): def __init__(self, operatorsymbol, arity, specialnames=None, **extras): """NOT_RPYTHON: cannot create new multimethods dynamically. Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Oct 27 01:13:13 2005 @@ -6,7 +6,7 @@ from pypy.interpreter.gateway import PyPyCacheDir from pypy.tool.cache import Cache from pypy.objspace.std.model import W_Object, UnwrapError -from pypy.objspace.std.model import W_ANY, MultiMethod, StdTypeModel +from pypy.objspace.std.model import W_ANY, StdObjspaceMultiMethod, StdTypeModel from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.descroperation import DescrOperation from pypy.objspace.std import stdtypedef @@ -40,7 +40,7 @@ # install all the MultiMethods into the space instance for name, mm in self.MM.__dict__.items(): - if isinstance(mm, MultiMethod) and not hasattr(self, name): + if isinstance(mm, StdObjspaceMultiMethod) and not hasattr(self, name): if name.endswith('_w'): # int_w, str_w...: these do not return a wrapped object func = mm.install_not_sliced(self.model.typeorder, baked_perform_call=True) else: @@ -431,21 +431,21 @@ class MM: "Container for multimethods." - call = MultiMethod('call', 1, ['__call__'], general__args__=True) - init = MultiMethod('__init__', 1, general__args__=True) - getnewargs = MultiMethod('__getnewargs__', 1) + call = StdObjspaceMultiMethod('call', 1, ['__call__'], general__args__=True) + init = StdObjspaceMultiMethod('__init__', 1, general__args__=True) + getnewargs = StdObjspaceMultiMethod('__getnewargs__', 1) # special visible multimethods - int_w = MultiMethod('int_w', 1, []) # returns an unwrapped int - 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=['marshaller']) - log = MultiMethod('log', 1, [], extra_args=['base']) + int_w = StdObjspaceMultiMethod('int_w', 1, []) # returns an unwrapped int + str_w = StdObjspaceMultiMethod('str_w', 1, []) # returns an unwrapped string + float_w = StdObjspaceMultiMethod('float_w', 1, []) # returns an unwrapped float + uint_w = StdObjspaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) + marshal_w = StdObjspaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) + log = StdObjspaceMultiMethod('log', 1, [], extra_args=['base']) # add all regular multimethods here for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: if _name not in locals(): - mm = MultiMethod(_symbol, _arity, _specialnames) + mm = StdObjspaceMultiMethod(_symbol, _arity, _specialnames) locals()[_name] = mm del mm Modified: pypy/dist/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/slicetype.py (original) +++ pypy/dist/pypy/objspace/std/slicetype.py Thu Oct 27 01:13:13 2005 @@ -5,7 +5,7 @@ from pypy.interpreter.error import OperationError # indices multimehtod -slice_indices = MultiMethod('indices', 2) +slice_indices = StdObjspaceMultiMethod('indices', 2) # utility functions def _Eval_SliceIndex(space, w_int): Modified: pypy/dist/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/dist/pypy/objspace/std/stdtypedef.py (original) +++ pypy/dist/pypy/objspace/std/stdtypedef.py Thu Oct 27 01:13:13 2005 @@ -3,13 +3,13 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.baseobjspace import SpaceCache -from pypy.objspace.std.model import MultiMethod +from pypy.objspace.std.model import StdObjspaceMultiMethod from pypy.objspace.std.multimethod import FailedToImplement from pypy.tool.sourcetools import compile2 __all__ = ['StdTypeDef', 'newmethod', 'gateway', 'GetSetProperty', 'Member', - 'MultiMethod', 'descr_get_dict'] + 'StdObjspaceMultiMethod', 'descr_get_dict'] class StdTypeDef(TypeDef): @@ -93,7 +93,7 @@ "NOT_RPYTHON: initialization-time only." result = [] for value in ns.itervalues(): - if isinstance(value, MultiMethod): + if isinstance(value, StdObjspaceMultiMethod): result.append(value) return result Modified: pypy/dist/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringtype.py (original) +++ pypy/dist/pypy/objspace/std/stringtype.py Thu Oct 27 01:13:13 2005 @@ -3,41 +3,41 @@ from sys import maxint -str_join = MultiMethod('join', 2) -str_split = MultiMethod('split', 3, defaults=(None,-1)) -str_rsplit = MultiMethod('rsplit', 3, defaults=(None,-1)) -str_isdigit = MultiMethod('isdigit', 1) -str_isalpha = MultiMethod('isalpha', 1) -str_isspace = MultiMethod('isspace', 1) -str_isupper = MultiMethod('isupper', 1) -str_islower = MultiMethod('islower', 1) -str_istitle = MultiMethod('istitle', 1) -str_isalnum = MultiMethod('isalnum', 1) -str_ljust = MultiMethod('ljust', 3, defaults=(' ',)) -str_rjust = MultiMethod('rjust', 3, defaults=(' ',)) -str_upper = MultiMethod('upper', 1) -str_lower = MultiMethod('lower', 1) -str_swapcase = MultiMethod('swapcase', 1) -str_capitalize = MultiMethod('capitalize', 1) -str_title = MultiMethod('title', 1) -str_find = MultiMethod('find', 4, defaults=(0, maxint)) -str_rfind = MultiMethod('rfind', 4, defaults=(0, maxint)) -str_index = MultiMethod('index', 4, defaults=(0, maxint)) -str_rindex = MultiMethod('rindex', 4, defaults=(0, maxint)) -str_replace = MultiMethod('replace', 4, defaults=(-1,)) -str_zfill = MultiMethod('zfill', 2) -str_strip = MultiMethod('strip', 2, defaults=(None,)) -str_rstrip = MultiMethod('rstrip', 2, defaults=(None,)) -str_lstrip = MultiMethod('lstrip', 2, defaults=(None,)) -str_center = MultiMethod('center', 3, defaults=(' ',)) -str_count = MultiMethod('count', 4, defaults=(0, maxint)) -str_endswith = MultiMethod('endswith', 4, defaults=(0, maxint)) -str_expandtabs = MultiMethod('expandtabs', 2, defaults=(8,)) -str_splitlines = MultiMethod('splitlines', 2, defaults=(0,)) -str_startswith = MultiMethod('startswith', 4, defaults=(0, maxint)) -str_translate = MultiMethod('translate', 3, defaults=('',)) #unicode mimic not supported now -str_decode = MultiMethod('decode', 3, defaults=(None, None)) -str_encode = MultiMethod('encode', 3, defaults=(None, None)) +str_join = StdObjspaceMultiMethod('join', 2) +str_split = StdObjspaceMultiMethod('split', 3, defaults=(None,-1)) +str_rsplit = StdObjspaceMultiMethod('rsplit', 3, defaults=(None,-1)) +str_isdigit = StdObjspaceMultiMethod('isdigit', 1) +str_isalpha = StdObjspaceMultiMethod('isalpha', 1) +str_isspace = StdObjspaceMultiMethod('isspace', 1) +str_isupper = StdObjspaceMultiMethod('isupper', 1) +str_islower = StdObjspaceMultiMethod('islower', 1) +str_istitle = StdObjspaceMultiMethod('istitle', 1) +str_isalnum = StdObjspaceMultiMethod('isalnum', 1) +str_ljust = StdObjspaceMultiMethod('ljust', 3, defaults=(' ',)) +str_rjust = StdObjspaceMultiMethod('rjust', 3, defaults=(' ',)) +str_upper = StdObjspaceMultiMethod('upper', 1) +str_lower = StdObjspaceMultiMethod('lower', 1) +str_swapcase = StdObjspaceMultiMethod('swapcase', 1) +str_capitalize = StdObjspaceMultiMethod('capitalize', 1) +str_title = StdObjspaceMultiMethod('title', 1) +str_find = StdObjspaceMultiMethod('find', 4, defaults=(0, maxint)) +str_rfind = StdObjspaceMultiMethod('rfind', 4, defaults=(0, maxint)) +str_index = StdObjspaceMultiMethod('index', 4, defaults=(0, maxint)) +str_rindex = StdObjspaceMultiMethod('rindex', 4, defaults=(0, maxint)) +str_replace = StdObjspaceMultiMethod('replace', 4, defaults=(-1,)) +str_zfill = StdObjspaceMultiMethod('zfill', 2) +str_strip = StdObjspaceMultiMethod('strip', 2, defaults=(None,)) +str_rstrip = StdObjspaceMultiMethod('rstrip', 2, defaults=(None,)) +str_lstrip = StdObjspaceMultiMethod('lstrip', 2, defaults=(None,)) +str_center = StdObjspaceMultiMethod('center', 3, defaults=(' ',)) +str_count = StdObjspaceMultiMethod('count', 4, defaults=(0, maxint)) +str_endswith = StdObjspaceMultiMethod('endswith', 4, defaults=(0, maxint)) +str_expandtabs = StdObjspaceMultiMethod('expandtabs', 2, defaults=(8,)) +str_splitlines = StdObjspaceMultiMethod('splitlines', 2, defaults=(0,)) +str_startswith = StdObjspaceMultiMethod('startswith', 4, defaults=(0, maxint)) +str_translate = StdObjspaceMultiMethod('translate', 3, defaults=('',)) #unicode mimic not supported now +str_decode = StdObjspaceMultiMethod('decode', 3, defaults=(None, None)) +str_encode = StdObjspaceMultiMethod('encode', 3, defaults=(None, None)) # ____________________________________________________________ Modified: pypy/dist/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodetype.py (original) +++ pypy/dist/pypy/objspace/std/unicodetype.py Thu Oct 27 01:13:13 2005 @@ -4,42 +4,42 @@ from sys import maxint -unicode_capitalize = MultiMethod('capitalize', 1) -unicode_center = MultiMethod('center', 3, defaults=(' ',)) -unicode_count = MultiMethod('count', 4, defaults=(0, maxint)) -unicode_encode = MultiMethod('encode', 3, defaults=(None, None)) -unicode_endswith = MultiMethod('endswith', 4, defaults=(0,maxint)) -unicode_expandtabs = MultiMethod('expandtabs', 2, defaults=(8,)) -unicode_find = MultiMethod('find', 4, defaults=(0, maxint)) -unicode_index = MultiMethod('index', 4, defaults=(0, maxint)) -unicode_isalnum = MultiMethod('isalnum', 1) -unicode_isalpha = MultiMethod('isalpha', 1) -unicode_isdecimal = MultiMethod('isdecimal', 1) -unicode_isdigit = MultiMethod('isdigit', 1) -unicode_islower = MultiMethod('islower', 1) -unicode_isnumeric = MultiMethod('isnumeric', 1) -unicode_isspace = MultiMethod('isspace', 1) -unicode_istitle = MultiMethod('istitle', 1) -unicode_isupper = MultiMethod('isupper', 1) -unicode_join = MultiMethod('join', 2) -unicode_ljust = MultiMethod('ljust', 3, defaults=(' ',)) -unicode_lower = MultiMethod('lower', 1) -unicode_lstrip = MultiMethod('lstrip', 2, defaults=(None,)) -unicode_replace = MultiMethod('replace', 4, defaults=(-1,)) -unicode_rfind = MultiMethod('rfind', 4, defaults=(0, maxint)) -unicode_rindex = MultiMethod('rindex', 4, defaults=(0, maxint)) -unicode_rjust = MultiMethod('rjust', 3, defaults=(' ',)) -unicode_rstrip = MultiMethod('rstrip', 2, defaults=(None,)) -unicode_rsplit = MultiMethod('rsplit', 3, defaults=(None,-1)) -unicode_split = MultiMethod('split', 3, defaults=(None,-1)) -unicode_splitlines = MultiMethod('splitlines', 2, defaults=(0,)) -unicode_startswith = MultiMethod('startswith', 4, defaults=(0,maxint)) -unicode_strip = MultiMethod('strip', 2, defaults=(None,)) -unicode_swapcase = MultiMethod('swapcase', 1) -unicode_title = MultiMethod('title', 1) -unicode_translate = MultiMethod('translate', 2) -unicode_upper = MultiMethod('upper', 1) -unicode_zfill = MultiMethod('zfill', 2) +unicode_capitalize = StdObjspaceMultiMethod('capitalize', 1) +unicode_center = StdObjspaceMultiMethod('center', 3, defaults=(' ',)) +unicode_count = StdObjspaceMultiMethod('count', 4, defaults=(0, maxint)) +unicode_encode = StdObjspaceMultiMethod('encode', 3, defaults=(None, None)) +unicode_endswith = StdObjspaceMultiMethod('endswith', 4, defaults=(0,maxint)) +unicode_expandtabs = StdObjspaceMultiMethod('expandtabs', 2, defaults=(8,)) +unicode_find = StdObjspaceMultiMethod('find', 4, defaults=(0, maxint)) +unicode_index = StdObjspaceMultiMethod('index', 4, defaults=(0, maxint)) +unicode_isalnum = StdObjspaceMultiMethod('isalnum', 1) +unicode_isalpha = StdObjspaceMultiMethod('isalpha', 1) +unicode_isdecimal = StdObjspaceMultiMethod('isdecimal', 1) +unicode_isdigit = StdObjspaceMultiMethod('isdigit', 1) +unicode_islower = StdObjspaceMultiMethod('islower', 1) +unicode_isnumeric = StdObjspaceMultiMethod('isnumeric', 1) +unicode_isspace = StdObjspaceMultiMethod('isspace', 1) +unicode_istitle = StdObjspaceMultiMethod('istitle', 1) +unicode_isupper = StdObjspaceMultiMethod('isupper', 1) +unicode_join = StdObjspaceMultiMethod('join', 2) +unicode_ljust = StdObjspaceMultiMethod('ljust', 3, defaults=(' ',)) +unicode_lower = StdObjspaceMultiMethod('lower', 1) +unicode_lstrip = StdObjspaceMultiMethod('lstrip', 2, defaults=(None,)) +unicode_replace = StdObjspaceMultiMethod('replace', 4, defaults=(-1,)) +unicode_rfind = StdObjspaceMultiMethod('rfind', 4, defaults=(0, maxint)) +unicode_rindex = StdObjspaceMultiMethod('rindex', 4, defaults=(0, maxint)) +unicode_rjust = StdObjspaceMultiMethod('rjust', 3, defaults=(' ',)) +unicode_rstrip = StdObjspaceMultiMethod('rstrip', 2, defaults=(None,)) +unicode_rsplit = StdObjspaceMultiMethod('rsplit', 3, defaults=(None,-1)) +unicode_split = StdObjspaceMultiMethod('split', 3, defaults=(None,-1)) +unicode_splitlines = StdObjspaceMultiMethod('splitlines', 2, defaults=(0,)) +unicode_startswith = StdObjspaceMultiMethod('startswith', 4, defaults=(0,maxint)) +unicode_strip = StdObjspaceMultiMethod('strip', 2, defaults=(None,)) +unicode_swapcase = StdObjspaceMultiMethod('swapcase', 1) +unicode_title = StdObjspaceMultiMethod('title', 1) +unicode_translate = StdObjspaceMultiMethod('translate', 2) +unicode_upper = StdObjspaceMultiMethod('upper', 1) +unicode_zfill = StdObjspaceMultiMethod('zfill', 2) # ____________________________________________________________ From mwh at codespeak.net Thu Oct 27 01:37:48 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 01:37:48 +0200 (CEST) Subject: [pypy-svn] r19047 - pypy/dist/pypy/interpreter Message-ID: <20051026233748.69FD027B61@code1.codespeak.net> Author: mwh Date: Thu Oct 27 01:37:47 2005 New Revision: 19047 Modified: pypy/dist/pypy/interpreter/interactive.py Log: fix from pyflakes via Jerub. Modified: pypy/dist/pypy/interpreter/interactive.py ============================================================================== --- pypy/dist/pypy/interpreter/interactive.py (original) +++ pypy/dist/pypy/interpreter/interactive.py Thu Oct 27 01:37:47 2005 @@ -77,7 +77,7 @@ w_bases = s.getattr(w_clz, s.wrap("__bases__")) bases_w = s.unpacktuple(w_bases) - except OperationError: + except error.OperationError: return words for w_clz in bases_w: From cfbolz at codespeak.net Thu Oct 27 01:43:44 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Oct 2005 01:43:44 +0200 (CEST) Subject: [pypy-svn] r19048 - pypy/dist/pypy/objspace/std Message-ID: <20051026234344.9CB1727B61@code1.codespeak.net> Author: cfbolz Date: Thu Oct 27 01:43:41 2005 New Revision: 19048 Modified: pypy/dist/pypy/objspace/std/dicttype.py pypy/dist/pypy/objspace/std/listtype.py pypy/dist/pypy/objspace/std/model.py pypy/dist/pypy/objspace/std/objspace.py pypy/dist/pypy/objspace/std/slicetype.py pypy/dist/pypy/objspace/std/stdtypedef.py pypy/dist/pypy/objspace/std/stringtype.py pypy/dist/pypy/objspace/std/unicodetype.py Log: oops Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Thu Oct 27 01:43:41 2005 @@ -2,21 +2,21 @@ from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError -dict_copy = StdObjspaceMultiMethod('copy', 1) -dict_items = StdObjspaceMultiMethod('items', 1) -dict_keys = StdObjspaceMultiMethod('keys', 1) -dict_values = StdObjspaceMultiMethod('values', 1) -dict_has_key = StdObjspaceMultiMethod('has_key', 2) -dict_clear = StdObjspaceMultiMethod('clear', 1) -dict_get = StdObjspaceMultiMethod('get', 3, defaults=(None,)) -dict_pop = StdObjspaceMultiMethod('pop', 2, w_varargs=True) -dict_popitem = StdObjspaceMultiMethod('popitem', 1) -dict_setdefault = StdObjspaceMultiMethod('setdefault', 3, defaults=(None,)) -dict_update = StdObjspaceMultiMethod('update', 2, defaults=((),)) -dict_iteritems = StdObjspaceMultiMethod('iteritems', 1) -dict_iterkeys = StdObjspaceMultiMethod('iterkeys', 1) -dict_itervalues = StdObjspaceMultiMethod('itervalues', 1) -dict_reversed = StdObjspaceMultiMethod('__reversed__', 1) +dict_copy = StdObjSpaceMultiMethod('copy', 1) +dict_items = StdObjSpaceMultiMethod('items', 1) +dict_keys = StdObjSpaceMultiMethod('keys', 1) +dict_values = StdObjSpaceMultiMethod('values', 1) +dict_has_key = StdObjSpaceMultiMethod('has_key', 2) +dict_clear = StdObjSpaceMultiMethod('clear', 1) +dict_get = StdObjSpaceMultiMethod('get', 3, defaults=(None,)) +dict_pop = StdObjSpaceMultiMethod('pop', 2, w_varargs=True) +dict_popitem = StdObjSpaceMultiMethod('popitem', 1) +dict_setdefault = StdObjSpaceMultiMethod('setdefault', 3, defaults=(None,)) +dict_update = StdObjSpaceMultiMethod('update', 2, defaults=((),)) +dict_iteritems = StdObjSpaceMultiMethod('iteritems', 1) +dict_iterkeys = StdObjSpaceMultiMethod('iterkeys', 1) +dict_itervalues = StdObjSpaceMultiMethod('itervalues', 1) +dict_reversed = StdObjSpaceMultiMethod('__reversed__', 1) def dict_reversed__ANY(space, w_dict): raise OperationError(space.w_TypeError, space.wrap('argument to reversed() must be a sequence')) Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Thu Oct 27 01:43:41 2005 @@ -3,16 +3,16 @@ from pypy.objspace.std.register_all import register_all from sys import maxint -list_append = StdObjspaceMultiMethod('append', 2) -list_insert = StdObjspaceMultiMethod('insert', 3) -list_extend = StdObjspaceMultiMethod('extend', 2) -list_pop = StdObjspaceMultiMethod('pop', 2, defaults=(-1,)) -list_remove = StdObjspaceMultiMethod('remove', 2) -list_index = StdObjspaceMultiMethod('index', 4, defaults=(0,maxint)) -list_count = StdObjspaceMultiMethod('count', 2) -list_reverse = StdObjspaceMultiMethod('reverse',1) -list_sort = StdObjspaceMultiMethod('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse']) -list_reversed = StdObjspaceMultiMethod('__reversed__', 1) +list_append = StdObjSpaceMultiMethod('append', 2) +list_insert = StdObjSpaceMultiMethod('insert', 3) +list_extend = StdObjSpaceMultiMethod('extend', 2) +list_pop = StdObjSpaceMultiMethod('pop', 2, defaults=(-1,)) +list_remove = StdObjSpaceMultiMethod('remove', 2) +list_index = StdObjSpaceMultiMethod('index', 4, defaults=(0,maxint)) +list_count = StdObjSpaceMultiMethod('count', 2) +list_reverse = StdObjSpaceMultiMethod('reverse',1) +list_sort = StdObjSpaceMultiMethod('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse']) +list_reversed = StdObjSpaceMultiMethod('__reversed__', 1) ## ### gateway is imported in the stdtypedef module ##list_reversed__ANY = gateway.applevel(''' Modified: pypy/dist/pypy/objspace/std/model.py ============================================================================== --- pypy/dist/pypy/objspace/std/model.py (original) +++ pypy/dist/pypy/objspace/std/model.py Thu Oct 27 01:43:41 2005 @@ -143,7 +143,7 @@ pass -class StdObjspaceMultiMethod(MultiMethodTable): +class StdObjSpaceMultiMethod(MultiMethodTable): def __init__(self, operatorsymbol, arity, specialnames=None, **extras): """NOT_RPYTHON: cannot create new multimethods dynamically. Modified: pypy/dist/pypy/objspace/std/objspace.py ============================================================================== --- pypy/dist/pypy/objspace/std/objspace.py (original) +++ pypy/dist/pypy/objspace/std/objspace.py Thu Oct 27 01:43:41 2005 @@ -6,7 +6,7 @@ from pypy.interpreter.gateway import PyPyCacheDir from pypy.tool.cache import Cache from pypy.objspace.std.model import W_Object, UnwrapError -from pypy.objspace.std.model import W_ANY, StdObjspaceMultiMethod, StdTypeModel +from pypy.objspace.std.model import W_ANY, StdObjSpaceMultiMethod, StdTypeModel from pypy.objspace.std.multimethod import FailedToImplement from pypy.objspace.descroperation import DescrOperation from pypy.objspace.std import stdtypedef @@ -40,7 +40,7 @@ # install all the MultiMethods into the space instance for name, mm in self.MM.__dict__.items(): - if isinstance(mm, StdObjspaceMultiMethod) and not hasattr(self, name): + if isinstance(mm, StdObjSpaceMultiMethod) and not hasattr(self, name): if name.endswith('_w'): # int_w, str_w...: these do not return a wrapped object func = mm.install_not_sliced(self.model.typeorder, baked_perform_call=True) else: @@ -431,21 +431,21 @@ class MM: "Container for multimethods." - call = StdObjspaceMultiMethod('call', 1, ['__call__'], general__args__=True) - init = StdObjspaceMultiMethod('__init__', 1, general__args__=True) - getnewargs = StdObjspaceMultiMethod('__getnewargs__', 1) + call = StdObjSpaceMultiMethod('call', 1, ['__call__'], general__args__=True) + init = StdObjSpaceMultiMethod('__init__', 1, general__args__=True) + getnewargs = StdObjSpaceMultiMethod('__getnewargs__', 1) # special visible multimethods - int_w = StdObjspaceMultiMethod('int_w', 1, []) # returns an unwrapped int - str_w = StdObjspaceMultiMethod('str_w', 1, []) # returns an unwrapped string - float_w = StdObjspaceMultiMethod('float_w', 1, []) # returns an unwrapped float - uint_w = StdObjspaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) - marshal_w = StdObjspaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) - log = StdObjspaceMultiMethod('log', 1, [], extra_args=['base']) + int_w = StdObjSpaceMultiMethod('int_w', 1, []) # returns an unwrapped int + str_w = StdObjSpaceMultiMethod('str_w', 1, []) # returns an unwrapped string + float_w = StdObjSpaceMultiMethod('float_w', 1, []) # returns an unwrapped float + uint_w = StdObjSpaceMultiMethod('uint_w', 1, []) # returns an unwrapped unsigned int (r_uint) + marshal_w = StdObjSpaceMultiMethod('marshal_w', 1, [], extra_args=['marshaller']) + log = StdObjSpaceMultiMethod('log', 1, [], extra_args=['base']) # add all regular multimethods here for _name, _symbol, _arity, _specialnames in ObjSpace.MethodTable: if _name not in locals(): - mm = StdObjspaceMultiMethod(_symbol, _arity, _specialnames) + mm = StdObjSpaceMultiMethod(_symbol, _arity, _specialnames) locals()[_name] = mm del mm Modified: pypy/dist/pypy/objspace/std/slicetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/slicetype.py (original) +++ pypy/dist/pypy/objspace/std/slicetype.py Thu Oct 27 01:43:41 2005 @@ -5,7 +5,7 @@ from pypy.interpreter.error import OperationError # indices multimehtod -slice_indices = StdObjspaceMultiMethod('indices', 2) +slice_indices = StdObjSpaceMultiMethod('indices', 2) # utility functions def _Eval_SliceIndex(space, w_int): Modified: pypy/dist/pypy/objspace/std/stdtypedef.py ============================================================================== --- pypy/dist/pypy/objspace/std/stdtypedef.py (original) +++ pypy/dist/pypy/objspace/std/stdtypedef.py Thu Oct 27 01:43:41 2005 @@ -3,13 +3,13 @@ from pypy.interpreter.typedef import TypeDef, GetSetProperty, Member from pypy.interpreter.typedef import descr_get_dict, descr_set_dict from pypy.interpreter.baseobjspace import SpaceCache -from pypy.objspace.std.model import StdObjspaceMultiMethod +from pypy.objspace.std.model import StdObjSpaceMultiMethod from pypy.objspace.std.multimethod import FailedToImplement from pypy.tool.sourcetools import compile2 __all__ = ['StdTypeDef', 'newmethod', 'gateway', 'GetSetProperty', 'Member', - 'StdObjspaceMultiMethod', 'descr_get_dict'] + 'StdObjSpaceMultiMethod', 'descr_get_dict'] class StdTypeDef(TypeDef): @@ -93,7 +93,7 @@ "NOT_RPYTHON: initialization-time only." result = [] for value in ns.itervalues(): - if isinstance(value, StdObjspaceMultiMethod): + if isinstance(value, StdObjSpaceMultiMethod): result.append(value) return result Modified: pypy/dist/pypy/objspace/std/stringtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/stringtype.py (original) +++ pypy/dist/pypy/objspace/std/stringtype.py Thu Oct 27 01:43:41 2005 @@ -3,41 +3,41 @@ from sys import maxint -str_join = StdObjspaceMultiMethod('join', 2) -str_split = StdObjspaceMultiMethod('split', 3, defaults=(None,-1)) -str_rsplit = StdObjspaceMultiMethod('rsplit', 3, defaults=(None,-1)) -str_isdigit = StdObjspaceMultiMethod('isdigit', 1) -str_isalpha = StdObjspaceMultiMethod('isalpha', 1) -str_isspace = StdObjspaceMultiMethod('isspace', 1) -str_isupper = StdObjspaceMultiMethod('isupper', 1) -str_islower = StdObjspaceMultiMethod('islower', 1) -str_istitle = StdObjspaceMultiMethod('istitle', 1) -str_isalnum = StdObjspaceMultiMethod('isalnum', 1) -str_ljust = StdObjspaceMultiMethod('ljust', 3, defaults=(' ',)) -str_rjust = StdObjspaceMultiMethod('rjust', 3, defaults=(' ',)) -str_upper = StdObjspaceMultiMethod('upper', 1) -str_lower = StdObjspaceMultiMethod('lower', 1) -str_swapcase = StdObjspaceMultiMethod('swapcase', 1) -str_capitalize = StdObjspaceMultiMethod('capitalize', 1) -str_title = StdObjspaceMultiMethod('title', 1) -str_find = StdObjspaceMultiMethod('find', 4, defaults=(0, maxint)) -str_rfind = StdObjspaceMultiMethod('rfind', 4, defaults=(0, maxint)) -str_index = StdObjspaceMultiMethod('index', 4, defaults=(0, maxint)) -str_rindex = StdObjspaceMultiMethod('rindex', 4, defaults=(0, maxint)) -str_replace = StdObjspaceMultiMethod('replace', 4, defaults=(-1,)) -str_zfill = StdObjspaceMultiMethod('zfill', 2) -str_strip = StdObjspaceMultiMethod('strip', 2, defaults=(None,)) -str_rstrip = StdObjspaceMultiMethod('rstrip', 2, defaults=(None,)) -str_lstrip = StdObjspaceMultiMethod('lstrip', 2, defaults=(None,)) -str_center = StdObjspaceMultiMethod('center', 3, defaults=(' ',)) -str_count = StdObjspaceMultiMethod('count', 4, defaults=(0, maxint)) -str_endswith = StdObjspaceMultiMethod('endswith', 4, defaults=(0, maxint)) -str_expandtabs = StdObjspaceMultiMethod('expandtabs', 2, defaults=(8,)) -str_splitlines = StdObjspaceMultiMethod('splitlines', 2, defaults=(0,)) -str_startswith = StdObjspaceMultiMethod('startswith', 4, defaults=(0, maxint)) -str_translate = StdObjspaceMultiMethod('translate', 3, defaults=('',)) #unicode mimic not supported now -str_decode = StdObjspaceMultiMethod('decode', 3, defaults=(None, None)) -str_encode = StdObjspaceMultiMethod('encode', 3, defaults=(None, None)) +str_join = StdObjSpaceMultiMethod('join', 2) +str_split = StdObjSpaceMultiMethod('split', 3, defaults=(None,-1)) +str_rsplit = StdObjSpaceMultiMethod('rsplit', 3, defaults=(None,-1)) +str_isdigit = StdObjSpaceMultiMethod('isdigit', 1) +str_isalpha = StdObjSpaceMultiMethod('isalpha', 1) +str_isspace = StdObjSpaceMultiMethod('isspace', 1) +str_isupper = StdObjSpaceMultiMethod('isupper', 1) +str_islower = StdObjSpaceMultiMethod('islower', 1) +str_istitle = StdObjSpaceMultiMethod('istitle', 1) +str_isalnum = StdObjSpaceMultiMethod('isalnum', 1) +str_ljust = StdObjSpaceMultiMethod('ljust', 3, defaults=(' ',)) +str_rjust = StdObjSpaceMultiMethod('rjust', 3, defaults=(' ',)) +str_upper = StdObjSpaceMultiMethod('upper', 1) +str_lower = StdObjSpaceMultiMethod('lower', 1) +str_swapcase = StdObjSpaceMultiMethod('swapcase', 1) +str_capitalize = StdObjSpaceMultiMethod('capitalize', 1) +str_title = StdObjSpaceMultiMethod('title', 1) +str_find = StdObjSpaceMultiMethod('find', 4, defaults=(0, maxint)) +str_rfind = StdObjSpaceMultiMethod('rfind', 4, defaults=(0, maxint)) +str_index = StdObjSpaceMultiMethod('index', 4, defaults=(0, maxint)) +str_rindex = StdObjSpaceMultiMethod('rindex', 4, defaults=(0, maxint)) +str_replace = StdObjSpaceMultiMethod('replace', 4, defaults=(-1,)) +str_zfill = StdObjSpaceMultiMethod('zfill', 2) +str_strip = StdObjSpaceMultiMethod('strip', 2, defaults=(None,)) +str_rstrip = StdObjSpaceMultiMethod('rstrip', 2, defaults=(None,)) +str_lstrip = StdObjSpaceMultiMethod('lstrip', 2, defaults=(None,)) +str_center = StdObjSpaceMultiMethod('center', 3, defaults=(' ',)) +str_count = StdObjSpaceMultiMethod('count', 4, defaults=(0, maxint)) +str_endswith = StdObjSpaceMultiMethod('endswith', 4, defaults=(0, maxint)) +str_expandtabs = StdObjSpaceMultiMethod('expandtabs', 2, defaults=(8,)) +str_splitlines = StdObjSpaceMultiMethod('splitlines', 2, defaults=(0,)) +str_startswith = StdObjSpaceMultiMethod('startswith', 4, defaults=(0, maxint)) +str_translate = StdObjSpaceMultiMethod('translate', 3, defaults=('',)) #unicode mimic not supported now +str_decode = StdObjSpaceMultiMethod('decode', 3, defaults=(None, None)) +str_encode = StdObjSpaceMultiMethod('encode', 3, defaults=(None, None)) # ____________________________________________________________ Modified: pypy/dist/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodetype.py (original) +++ pypy/dist/pypy/objspace/std/unicodetype.py Thu Oct 27 01:43:41 2005 @@ -4,42 +4,42 @@ from sys import maxint -unicode_capitalize = StdObjspaceMultiMethod('capitalize', 1) -unicode_center = StdObjspaceMultiMethod('center', 3, defaults=(' ',)) -unicode_count = StdObjspaceMultiMethod('count', 4, defaults=(0, maxint)) -unicode_encode = StdObjspaceMultiMethod('encode', 3, defaults=(None, None)) -unicode_endswith = StdObjspaceMultiMethod('endswith', 4, defaults=(0,maxint)) -unicode_expandtabs = StdObjspaceMultiMethod('expandtabs', 2, defaults=(8,)) -unicode_find = StdObjspaceMultiMethod('find', 4, defaults=(0, maxint)) -unicode_index = StdObjspaceMultiMethod('index', 4, defaults=(0, maxint)) -unicode_isalnum = StdObjspaceMultiMethod('isalnum', 1) -unicode_isalpha = StdObjspaceMultiMethod('isalpha', 1) -unicode_isdecimal = StdObjspaceMultiMethod('isdecimal', 1) -unicode_isdigit = StdObjspaceMultiMethod('isdigit', 1) -unicode_islower = StdObjspaceMultiMethod('islower', 1) -unicode_isnumeric = StdObjspaceMultiMethod('isnumeric', 1) -unicode_isspace = StdObjspaceMultiMethod('isspace', 1) -unicode_istitle = StdObjspaceMultiMethod('istitle', 1) -unicode_isupper = StdObjspaceMultiMethod('isupper', 1) -unicode_join = StdObjspaceMultiMethod('join', 2) -unicode_ljust = StdObjspaceMultiMethod('ljust', 3, defaults=(' ',)) -unicode_lower = StdObjspaceMultiMethod('lower', 1) -unicode_lstrip = StdObjspaceMultiMethod('lstrip', 2, defaults=(None,)) -unicode_replace = StdObjspaceMultiMethod('replace', 4, defaults=(-1,)) -unicode_rfind = StdObjspaceMultiMethod('rfind', 4, defaults=(0, maxint)) -unicode_rindex = StdObjspaceMultiMethod('rindex', 4, defaults=(0, maxint)) -unicode_rjust = StdObjspaceMultiMethod('rjust', 3, defaults=(' ',)) -unicode_rstrip = StdObjspaceMultiMethod('rstrip', 2, defaults=(None,)) -unicode_rsplit = StdObjspaceMultiMethod('rsplit', 3, defaults=(None,-1)) -unicode_split = StdObjspaceMultiMethod('split', 3, defaults=(None,-1)) -unicode_splitlines = StdObjspaceMultiMethod('splitlines', 2, defaults=(0,)) -unicode_startswith = StdObjspaceMultiMethod('startswith', 4, defaults=(0,maxint)) -unicode_strip = StdObjspaceMultiMethod('strip', 2, defaults=(None,)) -unicode_swapcase = StdObjspaceMultiMethod('swapcase', 1) -unicode_title = StdObjspaceMultiMethod('title', 1) -unicode_translate = StdObjspaceMultiMethod('translate', 2) -unicode_upper = StdObjspaceMultiMethod('upper', 1) -unicode_zfill = StdObjspaceMultiMethod('zfill', 2) +unicode_capitalize = StdObjSpaceMultiMethod('capitalize', 1) +unicode_center = StdObjSpaceMultiMethod('center', 3, defaults=(' ',)) +unicode_count = StdObjSpaceMultiMethod('count', 4, defaults=(0, maxint)) +unicode_encode = StdObjSpaceMultiMethod('encode', 3, defaults=(None, None)) +unicode_endswith = StdObjSpaceMultiMethod('endswith', 4, defaults=(0,maxint)) +unicode_expandtabs = StdObjSpaceMultiMethod('expandtabs', 2, defaults=(8,)) +unicode_find = StdObjSpaceMultiMethod('find', 4, defaults=(0, maxint)) +unicode_index = StdObjSpaceMultiMethod('index', 4, defaults=(0, maxint)) +unicode_isalnum = StdObjSpaceMultiMethod('isalnum', 1) +unicode_isalpha = StdObjSpaceMultiMethod('isalpha', 1) +unicode_isdecimal = StdObjSpaceMultiMethod('isdecimal', 1) +unicode_isdigit = StdObjSpaceMultiMethod('isdigit', 1) +unicode_islower = StdObjSpaceMultiMethod('islower', 1) +unicode_isnumeric = StdObjSpaceMultiMethod('isnumeric', 1) +unicode_isspace = StdObjSpaceMultiMethod('isspace', 1) +unicode_istitle = StdObjSpaceMultiMethod('istitle', 1) +unicode_isupper = StdObjSpaceMultiMethod('isupper', 1) +unicode_join = StdObjSpaceMultiMethod('join', 2) +unicode_ljust = StdObjSpaceMultiMethod('ljust', 3, defaults=(' ',)) +unicode_lower = StdObjSpaceMultiMethod('lower', 1) +unicode_lstrip = StdObjSpaceMultiMethod('lstrip', 2, defaults=(None,)) +unicode_replace = StdObjSpaceMultiMethod('replace', 4, defaults=(-1,)) +unicode_rfind = StdObjSpaceMultiMethod('rfind', 4, defaults=(0, maxint)) +unicode_rindex = StdObjSpaceMultiMethod('rindex', 4, defaults=(0, maxint)) +unicode_rjust = StdObjSpaceMultiMethod('rjust', 3, defaults=(' ',)) +unicode_rstrip = StdObjSpaceMultiMethod('rstrip', 2, defaults=(None,)) +unicode_rsplit = StdObjSpaceMultiMethod('rsplit', 3, defaults=(None,-1)) +unicode_split = StdObjSpaceMultiMethod('split', 3, defaults=(None,-1)) +unicode_splitlines = StdObjSpaceMultiMethod('splitlines', 2, defaults=(0,)) +unicode_startswith = StdObjSpaceMultiMethod('startswith', 4, defaults=(0,maxint)) +unicode_strip = StdObjSpaceMultiMethod('strip', 2, defaults=(None,)) +unicode_swapcase = StdObjSpaceMultiMethod('swapcase', 1) +unicode_title = StdObjSpaceMultiMethod('title', 1) +unicode_translate = StdObjSpaceMultiMethod('translate', 2) +unicode_upper = StdObjSpaceMultiMethod('upper', 1) +unicode_zfill = StdObjSpaceMultiMethod('zfill', 2) # ____________________________________________________________ From mwh at codespeak.net Thu Oct 27 01:59:53 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 01:59:53 +0200 (CEST) Subject: [pypy-svn] r19049 - pypy/dist/pypy/tool Message-ID: <20051026235953.BE88B27B50@code1.codespeak.net> Author: mwh Date: Thu Oct 27 01:59:52 2005 New Revision: 19049 Modified: pypy/dist/pypy/tool/importfun.py Log: more changes: keeps track of what names are imported by an 'import *' now. can complain if it's not obvious how a LOAD_GLOBAL can work, but we do too many exec tricks for this to be useful, so it's commented out. Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Thu Oct 27 01:59:52 2005 @@ -4,6 +4,7 @@ import imp import os from sys import path, prefix +import __builtin__ """ so design goal: @@ -118,10 +119,21 @@ class Module(object): - def __init__(self, system): + def __init__(self, name, system): + self.name = name self.system = system self._imports = {} # {modname:{name:was-it-used?}} - self.definitions = [] + self.definitions = ['__file__'] + if name == 'pypy.objspace.std.objspace': + self.definitions.extend([ + 'W_NoneObject', 'W_BoolObject', 'W_BoolObject', 'W_TypeObject', + 'W_TypeObject', 'W_TypeObject', 'W_IntObject', + 'W_StringObject', 'W_UnicodeObject', 'W_FloatObject', + 'W_TupleObject', 'W_ListObject', 'W_LongObject', 'W_SliceObject', + 'W_IntObject', 'W_FloatObject', 'W_LongObject', 'W_TupleObject', + 'W_ListObject', 'W_DictObject', 'W_SliceObject', + 'W_StringObject', 'W_UnicodeObject', 'W_SeqIterObject', + 'W_TupleObject', 'W_DictObject', 'W_DictObject']) self.toplevelscope = Scope() self.importers = [] def import_(self, modname): @@ -205,6 +217,19 @@ scope.modvars[storename] = modname.split('.')[0] i += 1 elif fromlist == ('*',): + assert toplevel + if modname.startswith('pypy.'): + if modname not in r.system.modules: + if modname in r.system.pendingmodules: + del r.system.pendingmodules[modname] + process_module(modname, r.system) + M = r.system.modules[modname] + for d in M.definitions + list(M.toplevelscope.modvars) + \ + [a[1] for a in M.toplevelscope.varsources.itervalues()]: + if d[0] != '_': + #print '* got ', d + scope.varsources[d] = modname, d + r.import_(modname)[d] = -1 r.import_(modname)['*'] = True else: # ok, this is from foo import bar @@ -276,6 +301,13 @@ if m: assert a in r.import_(m) r.import_(m)[a] = True +## else: +## if name not in r.definitions \ +## and scope.mod_for_name(name) is None \ +## and scope.var_source(name) == (None, None) \ +## and name not in __builtin__.__dict__ \ +## and (op == LOAD_GLOBAL or toplevel): +## print 'where did', name, 'come from?' elif op in [LOAD_FAST]: name = codeob.co_varnames[oparg] m, a = scope.var_source(name) @@ -307,7 +339,7 @@ ispackage = True path += '/__init__.py' code = compile(open(path, "U").read(), '', 'exec') - r = Module(system) + r = Module(dottedname, system) r.ispackage = ispackage try: @@ -357,6 +389,7 @@ print '------' for name, mod in sorted(system.modules.iteritems()): + printed = False if not 'pypy.' in name or '_cache' in name: continue u = {} @@ -367,9 +400,13 @@ for field, used in mod._imports[n].iteritems(): if n in system.modules: M = system.modules[n] - if not M.ispackage and field != '*' and field not in M.definitions: - print '***', name - print field, 'used from', n, 'but not defined there' + if not M.ispackage and field != '*' and field not in M.definitions \ + and used != -1: + if not printed: + print '*', name + printed = True + sourcemod, nam = M.toplevelscope.var_source(field) + print ' ', field, 'used from', n, 'but came from', sourcemod if not used: u.setdefault(n, []).append(field) else: @@ -380,7 +417,9 @@ else: u[n] = 'entirely' if u: - print name + if not printed: + print '*', name + printed = True for k, v in u.iteritems(): print ' ', k, v From pedronis at codespeak.net Thu Oct 27 03:15:13 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 27 Oct 2005 03:15:13 +0200 (CEST) Subject: [pypy-svn] r19050 - in pypy/dist/pypy/rpython: . test Message-ID: <20051027011513.0578127B86@code1.codespeak.net> Author: pedronis Date: Thu Oct 27 03:15:06 2005 New Revision: 19050 Modified: pypy/dist/pypy/rpython/rtuple.py pypy/dist/pypy/rpython/test/test_rtuple.py Log: type erase tuples, avoid a spurious tuple creation in binop descroperation translated code (with as it is now the lookup patch) Modified: pypy/dist/pypy/rpython/rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/rtuple.py (original) +++ pypy/dist/pypy/rpython/rtuple.py Thu Oct 27 03:15:06 2005 @@ -4,6 +4,7 @@ from pypy.rpython.error import TyperError from pypy.rpython.rmodel import Repr, IntegerRepr, inputconst from pypy.rpython.rmodel import IteratorRepr +from pypy.rpython.rmodel import externalvsinternal from pypy.rpython.robject import PyObjRepr, pyobj_repr from pypy.rpython.lltypesystem.lltype import \ Ptr, GcStruct, Void, Signed, malloc, typeOf, nullptr @@ -21,7 +22,7 @@ class __extend__(annmodel.SomeTuple): def rtyper_makerepr(self, rtyper): - return TupleRepr([rtyper.getrepr(s_item) for s_item in self.items]) + return TupleRepr(rtyper, [rtyper.getrepr(s_item) for s_item in self.items]) def rtyper_makekey_ex(self, rtyper): keys = [rtyper.makekey(s_item) for s_item in self.items] @@ -30,8 +31,14 @@ class TupleRepr(Repr): - def __init__(self, items_r): - self.items_r = items_r + def __init__(self, rtyper, items_r): + self.items_r = [] + self.external_items_r = [] + for item_r in items_r: + external_repr, internal_repr = externalvsinternal(rtyper, item_r) + self.items_r.append(internal_repr) + self.external_items_r.append(external_repr) + items_r = self.items_r self.fieldnames = ['item%d' % i for i in range(len(items_r))] self.lltypes = [r.lowleveltype for r in items_r] fields = zip(self.fieldnames, self.lltypes) @@ -82,11 +89,12 @@ return Length1TupleIteratorRepr(self) raise TyperError("can only iterate over tuples of length 1 for now") - def getitem(self, llops, v_tuple, index): + def getitem(self, llops, v_tuple, index): # ! returns internal repr lowleveltype name = self.fieldnames[index] llresult = self.lltypes[index] cname = inputconst(Void, name) - return llops.genop('getfield', [v_tuple, cname], resulttype = llresult) + return llops.genop('getfield', [v_tuple, cname], resulttype = llresult) + class __extend__(pairtype(TupleRepr, Repr)): @@ -117,7 +125,8 @@ if not isinstance(v_index, Constant): raise TyperError("non-constant tuple index") index = v_index.value - return r_tup.getitem(hop.llops, v_tuple, index) + v = r_tup.getitem(hop.llops, v_tuple, index) + return hop.llops.convertvar(v, r_tup.items_r[index], r_tup.external_items_r[index]) class __extend__(pairtype(TupleRepr, TupleRepr)): @@ -133,6 +142,8 @@ def convert_from_to((r_from, r_to), v, llops): if len(r_from.items_r) == len(r_to.items_r): + if r_from.lowleveltype == r_to.lowleveltype: + return v n = len(r_from.items_r) items_v = [] for i in range(n): @@ -148,7 +159,7 @@ # # Irregular operations. -def newtuple(llops, r_tuple, items_v): +def newtuple(llops, r_tuple, items_v): # items_v should have the lowleveltype of the internal reprs if len(r_tuple.items_r) == 0: return inputconst(r_tuple, ()) # always the same empty tuple c1 = inputconst(Void, r_tuple.lowleveltype.TO) @@ -221,7 +232,8 @@ 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) + v = hop.gendirectcall(ll_tuplenext, v_iter) + return hop.llops.convertvar(v, self.r_tuple.items_r[0], self.r_tuple.external_items_r[0]) def ll_tupleiter(ITERPTR, tuple): iter = malloc(ITERPTR.TO) Modified: pypy/dist/pypy/rpython/test/test_rtuple.py ============================================================================== --- pypy/dist/pypy/rpython/test/test_rtuple.py (original) +++ pypy/dist/pypy/rpython/test/test_rtuple.py Thu Oct 27 03:15:06 2005 @@ -8,7 +8,7 @@ import py def test_rtuple(): - rtuple = TupleRepr([signed_repr, bool_repr]) + rtuple = TupleRepr(None, [signed_repr, bool_repr]) assert rtuple.lowleveltype == Ptr(GcStruct('tuple2', ('item0', Signed), ('item1', Bool), @@ -134,3 +134,61 @@ return g(5) res = interpret(f, []) assert res is True + +def test_inst_tuple_getitem(): + class A: + pass + class B(A): + pass + + def f(i): + if i: + x = (1, A()) + else: + x = (1, B()) + return x[1] + + res = interpret(f, [0]) + assert ''.join(res.super.typeptr.name) == "B\00" + +def test_inst_tuple_iter(): + class A: + pass + class B(A): + pass + + def f(i): + if i: + x = (A(),) + else: + x = (B(),) + l = [] + for y in x: + l.append(y) + return l[0] + + res = interpret(f, [0]) + assert ''.join(res.super.typeptr.name) == "B\00" + + +def test_inst_tuple_add_getitem(): + class A: + pass + class B(A): + pass + + def f(i): + x = (1, A()) + y = (2, B()) + if i: + z = x + y + else: + z = y + x + return z[1] + + res = interpret(f, [1]) + assert ''.join(res.super.typeptr.name) == "A\00" + + res = interpret(f, [0]) + assert ''.join(res.super.typeptr.name) == "B\00" + From rxe at codespeak.net Thu Oct 27 05:40:50 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 27 Oct 2005 05:40:50 +0200 (CEST) Subject: [pypy-svn] r19054 - pypy/dist/pypy/translator/llvm Message-ID: <20051027034050.213DC27B86@code1.codespeak.net> Author: rxe Date: Thu Oct 27 05:40:48 2005 New Revision: 19054 Modified: pypy/dist/pypy/translator/llvm/externs2ll.py Log: Small fix to pass tests again. This same trick will need to be employed if there are more relative '#include's from the ll_xxx.h genc files. These disgusting hacks are there in genllvm because we run the llvm-gcc on a different machine (which I am not entirely sure is a good idea anymore :-( ) Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Thu Oct 27 05:40:48 2005 @@ -116,6 +116,12 @@ return decls +def path_join(root_path, *paths): + path = root_path + for p in paths: + path = os.path.join(path, p) + return path + def generate_llfile(db, extern_decls, support_functions, debug=False): ccode = [] function_names = [] @@ -140,22 +146,29 @@ predeclarefn(c_name, db.repr_name(obj._obj)) include_files = [] - # append local file - j = os.path.join - include_files.append(j(j(os.path.dirname(__file__), "module"), "genexterns.c")) + add = include_files.append + add(path_join(os.path.dirname(__file__), "module", "genexterns.c")) from pypy.translator.c import extfunc + src_path = path_join(os.path.dirname(extfunc.__file__), "src") + for f in ["ll_os", "ll_math", "ll_time", "ll_strtod", "stack"]: - include_files.append(j(j(os.path.dirname(extfunc.__file__), "src"), f + ".h")) + add(path_join(src_path, f + ".h")) for f in include_files: s = open(f).read() - if f.find('genexterns.c'): + if f.find('genexterns.c') > 0: if sys.platform == 'darwin': python_h = '"/System/Library/Frameworks/Python.framework/Versions/2.3/include/python2.3/Python.h"' else: python_h = '' s = s.replace('__PYTHON_H__', python_h) + + elif f.find("ll_os") > 0: + # XXX this is getting a tad ridiculous + ll_osdefs = open(path_join(src_path, "ll_osdefs.h")).read() + s = s.replace('#include "ll_osdefs.h"', ll_osdefs) + ccode.append(s) ccode = "".join(ccode) From rxe at codespeak.net Thu Oct 27 07:20:08 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 27 Oct 2005 07:20:08 +0200 (CEST) Subject: [pypy-svn] r19055 - pypy/dist/pypy/translator/llvm/test Message-ID: <20051027052008.5031727B59@code1.codespeak.net> Author: rxe Date: Thu Oct 27 07:20:05 2005 New Revision: 19055 Modified: pypy/dist/pypy/translator/llvm/test/test_extfunc.py Log: More tests from genc (one failing because of opaque type - skipping). Modified: pypy/dist/pypy/translator/llvm/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_extfunc.py Thu Oct 27 07:20:05 2005 @@ -7,6 +7,7 @@ from pypy.tool.udir import udir from pypy.translator.llvm.test.runtest import compile_function from pypy.rpython.rarithmetic import r_uint +from pypy.rpython import ros def test_external_function_ll_os_dup(): def fn(): @@ -292,4 +293,83 @@ f1(True) assert not os.path.exists(path) +# more from translator/c/test/test_extfunc.py Revision: 19054 + + +def _real_getenv(var): + cmd = '''%s -c "import os; x=os.environ.get('%s'); print (x is None) and 'F' or ('T'+x)"''' % ( + sys.executable, var) + g = os.popen(cmd, 'r') + output = g.read().strip() + g.close() + if output == 'F': + return None + elif output.startswith('T'): + return output[1:] + else: + raise ValueError, 'probing for env var returned %r' % (output,) + +def _real_envkeys(): + cmd = '''%s -c "import os; print os.environ.keys()"''' % sys.executable + g = os.popen(cmd, 'r') + output = g.read().strip() + g.close() + if output.startswith('[') and output.endswith(']'): + return eval(output) + else: + raise ValueError, 'probing for all env vars returned %r' % (output,) + +def test_putenv(): + s = 'abcdefgh=12345678' + def put(): + ros.putenv(s) + return 0 + func = compile_function(put, []) + func() + assert _real_getenv('abcdefgh') == '12345678' + +posix = __import__(os.name) +if hasattr(posix, "unsetenv"): + def test_unsetenv(): + def unsetenv(): + os.unsetenv("ABCDEF") + return 0 + f = compile_function(unsetenv, []) + os.putenv("ABCDEF", "a") + assert _real_getenv('ABCDEF') == 'a' + f() + assert _real_getenv('ABCDEF') is None + f() + assert _real_getenv('ABCDEF') is None + +def test_opendir_readdir(): + py.test.skip("XXX need to implement opaque types") + s = str(udir) + result = [] + def mylistdir(): + dir = ros.opendir(s) + try: + while True: + nextentry = dir.readdir() + if nextentry is None: + break + result.append(nextentry) + finally: + dir.closedir() + return 0 + func = compile_function(mylistdir, []) + result = func() + result = result.split('\x00') + assert '.' in result + assert '..' in result + result.remove('.') + result.remove('..') + result.sort() + compared_with = os.listdir(str(udir)) + compared_with.sort() + assert result == compared_with + # end of tests taken from c backend + + + From ericvrp at codespeak.net Thu Oct 27 09:08:08 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 27 Oct 2005 09:08:08 +0200 (CEST) Subject: [pypy-svn] r19057 - in pypy/dist/pypy/translator/llvm: . module Message-ID: <20051027070808.4811E27B76@code1.codespeak.net> Author: ericvrp Date: Thu Oct 27 09:08:07 2005 New Revision: 19057 Modified: pypy/dist/pypy/translator/llvm/build_llvm_module.py pypy/dist/pypy/translator/llvm/externs2ll.py pypy/dist/pypy/translator/llvm/module/genexterns.c Log: Sligtly better warnings in case gcc-llvm or upx is not available locally. LLVM 1.6 will come out in a weeks time. We should see if using gcc-llvm remotely (on codespeak) is still a good idea by then. (gcc-llvm does not seem too hard to install after all) note: this was not the reason for the failing tests. (rxe fixed those in r19054 (thanks!)) 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 Thu Oct 27 09:08:07 2005 @@ -114,8 +114,8 @@ if cleanup and exe_name and not profile: cmds.append('strip ' + exe_name) - upx = os.popen('which upx').read() - if upx: #compress file even further + upx = os.popen('which upx 2>&1').read() + if upx and not upx.startswith('which'): #compress file even further cmds.append('upx ' + exe_name) try: Modified: pypy/dist/pypy/translator/llvm/externs2ll.py ============================================================================== --- pypy/dist/pypy/translator/llvm/externs2ll.py (original) +++ pypy/dist/pypy/translator/llvm/externs2ll.py Thu Oct 27 09:08:07 2005 @@ -15,8 +15,9 @@ f = open(filename, "w") f.write(ccode) f.close() - - if os.popen('which llvm-gcc').read(): #local llvm CFE available + + llvm_gcc = os.popen('which llvm-gcc 2>&1').read() + if llvm_gcc and not llvm_gcc.startswith('which'): #local llvm CFE available #log('using local llvm-gcc') plain = filename[:-2] os.system("llvm-gcc -S %s.c -o %s.ll 2>&1" % (plain, plain)) @@ -74,7 +75,10 @@ ll_lines2.append(line) llcode = '\n'.join(ll_lines2) - decl, impl = llcode.split('implementation') + try: + decl, impl = llcode.split('implementation') + except: + raise "Can't compile external function code (llcode.c): ERROR:", llcode impl += """;functions that should return a bool according to ; pypy/rpython/extfunctable.py , but C doesn't have bools! Modified: pypy/dist/pypy/translator/llvm/module/genexterns.c ============================================================================== --- pypy/dist/pypy/translator/llvm/module/genexterns.c (original) +++ pypy/dist/pypy/translator/llvm/module/genexterns.c Thu Oct 27 09:08:07 2005 @@ -24,9 +24,4 @@ //the placeholder in the next line gets replaced by the actual python.h path #include __PYTHON_H__ -// Do this manually from python :-( -//#include "ll_os.h" -//#include "ll_math.h" -//#include "ll_time.h" -//#include "ll_strtod.h" - +// Append some genc files here manually from python From rxe at codespeak.net Thu Oct 27 09:19:24 2005 From: rxe at codespeak.net (rxe at codespeak.net) Date: Thu, 27 Oct 2005 09:19:24 +0200 (CEST) Subject: [pypy-svn] r19058 - in pypy/dist/pypy/translator/llvm: . test Message-ID: <20051027071924.9611D27B83@code1.codespeak.net> Author: rxe Date: Thu Oct 27 09:19:22 2005 New Revision: 19058 Modified: pypy/dist/pypy/translator/llvm/opaquenode.py pypy/dist/pypy/translator/llvm/test/test_extfunc.py Log: Quick fixes to opaque type. Should compile pypy again (not tested). Gnite (really going to bed this time.) Modified: pypy/dist/pypy/translator/llvm/opaquenode.py ============================================================================== --- pypy/dist/pypy/translator/llvm/opaquenode.py (original) +++ pypy/dist/pypy/translator/llvm/opaquenode.py Thu Oct 27 09:19:22 2005 @@ -7,7 +7,7 @@ assert isinstance(opaquetype, lltype.OpaqueType) self.db = db self.opaquetype = opaquetype - self.ref = "%%opaquetype.%s" % (opaquetype.tag) + self.ref = "%%RPyOpaque_%s" % (opaquetype.tag) def __str__(self): return "" %(self.ref,) @@ -17,7 +17,7 @@ def writedatatypedecl(self, codewriter): # XXX Dummy - not sure what what we want - codewriter.funcdef(self.ref, 'sbyte*', ['sbyte *']) + codewriter.append("%s = type sbyte*" % self.ref) class OpaqueNode(ConstantLLVMNode): Modified: pypy/dist/pypy/translator/llvm/test/test_extfunc.py ============================================================================== --- pypy/dist/pypy/translator/llvm/test/test_extfunc.py (original) +++ pypy/dist/pypy/translator/llvm/test/test_extfunc.py Thu Oct 27 09:19:22 2005 @@ -343,7 +343,6 @@ assert _real_getenv('ABCDEF') is None def test_opendir_readdir(): - py.test.skip("XXX need to implement opaque types") s = str(udir) result = [] def mylistdir(): @@ -359,6 +358,8 @@ return 0 func = compile_function(mylistdir, []) result = func() + py.test.skip("XXX need to check result - somehow") + result = result.split('\x00') assert '.' in result assert '..' in result From hpk at codespeak.net Thu Oct 27 11:27:52 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Thu, 27 Oct 2005 11:27:52 +0200 (CEST) Subject: [pypy-svn] r19060 - pypy/extradoc/talk/pycon2006 Message-ID: <20051027092752.9C4F027B58@code1.codespeak.net> Author: hpk Date: Thu Oct 27 11:27:50 2005 New Revision: 19060 Added: pypy/extradoc/talk/pycon2006/pypy-archsession.txt (contents, props changed) Log: first draft of an architectural session pycon proposal Added: pypy/extradoc/talk/pycon2006/pypy-archsession.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2006/pypy-archsession.txt Thu Oct 27 11:27:50 2005 @@ -0,0 +1,47 @@ +Author Names +------------ + +(from) Michael Hudson, Holger Krekel, Armin Rigo, Christian Tismer + +Contact Information +------------------- + +pypy-dev? + +Requested Timeslot +------------------ + +45 minutes or 30 minutes. both possible. + +Summary of proposed presentation +-------------------------------- + +After reaching important milestones, the PyPy project is +now heading towards building a specializing JIT-compiler, +stackless features and translation to higher level languages +into the code base. In this session we will present +and interactively discuss with the audience basic +architectural pictures. We'd are going to emphasize the +various emerging possibilities for further development +part of which will be an ongoing effort of the +European Union's funded part of the PyPy project. + +Presentation Outline +-------------------- + +We'll describe architectural pictures and point +out extension and optimization possibilities: + +- Language Implementation: Bytecode Interpreter and Object Space interaction +- Translation to low level languages (C/LLVM) +- Translation to higher level languages (e.g. Squeak/Java) +- JIT-compiler architecture (very-low-level interpreter) +- Interweaving of Garbage Collection, threading and stackless + operations into the translation process + +Intended audience +----------------- + +People who feel comfortable with receiving too much information +and accept that there are more levels of architecture involved +than a single person can instantly cope with. From mwh at codespeak.net Thu Oct 27 12:13:04 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 12:13:04 +0200 (CEST) Subject: [pypy-svn] r19062 - pypy/dist/pypy/objspace/std Message-ID: <20051027101304.6708727B83@code1.codespeak.net> Author: mwh Date: Thu Oct 27 12:13:03 2005 New Revision: 19062 Modified: pypy/dist/pypy/objspace/std/dictproxytype.py Log: another unnecessary import! Modified: pypy/dist/pypy/objspace/std/dictproxytype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dictproxytype.py (original) +++ pypy/dist/pypy/objspace/std/dictproxytype.py Thu Oct 27 12:13:03 2005 @@ -1,5 +1,4 @@ from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError # ____________________________________________________________ From mwh at codespeak.net Thu Oct 27 12:15:49 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 12:15:49 +0200 (CEST) Subject: [pypy-svn] r19063 - pypy/dist/pypy/objspace/std Message-ID: <20051027101549.F2B6127B83@code1.codespeak.net> Author: mwh Date: Thu Oct 27 12:15:49 2005 New Revision: 19063 Modified: pypy/dist/pypy/objspace/std/dicttype.py Log: add an explicit import of gateway (it came it from the 'import *' from stdtypedef but... ick) Modified: pypy/dist/pypy/objspace/std/dicttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/dicttype.py (original) +++ pypy/dist/pypy/objspace/std/dicttype.py Thu Oct 27 12:15:49 2005 @@ -1,3 +1,4 @@ +from pypy.interpreter import gateway from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from pypy.interpreter.error import OperationError From mwh at codespeak.net Thu Oct 27 12:19:53 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 12:19:53 +0200 (CEST) Subject: [pypy-svn] r19064 - pypy/dist/pypy/objspace/std Message-ID: <20051027101953.50B6B27B82@code1.codespeak.net> Author: mwh Date: Thu Oct 27 12:19:52 2005 New Revision: 19064 Modified: pypy/dist/pypy/objspace/std/fake.py Log: make some imports a little more sane. Modified: pypy/dist/pypy/objspace/std/fake.py ============================================================================== --- pypy/dist/pypy/objspace/std/fake.py (original) +++ pypy/dist/pypy/objspace/std/fake.py Thu Oct 27 12:19:52 2005 @@ -3,7 +3,6 @@ from pypy.interpreter import eval from pypy.interpreter.function import Function, BuiltinFunction from pypy.objspace.std.stdtypedef import * -from pypy.objspace.std.objspace import StdObjSpace from pypy.objspace.std.model import W_Object, UnwrapError # this file automatically generates non-reimplementations of CPython @@ -99,9 +98,9 @@ return w_obj kw['__new__'] = gateway.interp2app(fake__new__, - unwrap_spec = [baseobjspace.ObjSpace, - baseobjspace.W_Root, - gateway.Arguments]) + unwrap_spec=[baseobjspace.ObjSpace, + baseobjspace.W_Root, + argument.Arguments]) if cpy_type.__base__ is not object: assert cpy_type.__base__ is basestring from pypy.objspace.std.basestringtype import basestring_typedef @@ -193,7 +192,7 @@ from pypy.interpreter.baseobjspace import Wrappable from pypy.interpreter.typedef import TypeDef -from pypy.interpreter.gateway import interp2app +from pypy.interpreter import gateway, argument class W_FakeDescriptor(Wrappable): # Mimics pypy.interpreter.typedef.GetSetProperty. From mwh at codespeak.net Thu Oct 27 12:23:26 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 12:23:26 +0200 (CEST) Subject: [pypy-svn] r19065 - pypy/dist/pypy/objspace/std Message-ID: <20051027102326.8383627B83@code1.codespeak.net> Author: mwh Date: Thu Oct 27 12:23:24 2005 New Revision: 19065 Modified: pypy/dist/pypy/objspace/std/dump_multimethod.py pypy/dist/pypy/objspace/std/listtype.py pypy/dist/pypy/objspace/std/objecttype.py pypy/dist/pypy/objspace/std/typetype.py pypy/dist/pypy/objspace/std/unicodetype.py Log: some more explicit imports of gateway Modified: pypy/dist/pypy/objspace/std/dump_multimethod.py ============================================================================== --- pypy/dist/pypy/objspace/std/dump_multimethod.py (original) +++ pypy/dist/pypy/objspace/std/dump_multimethod.py Thu Oct 27 12:23:24 2005 @@ -23,7 +23,6 @@ def import_implementations(): # populate the multimethod tables by importing all object implementations - from pypy.objspace.std import default result = [] for fullpath in IMPLEMENTATIONS: i = fullpath.rfind('.') Modified: pypy/dist/pypy/objspace/std/listtype.py ============================================================================== --- pypy/dist/pypy/objspace/std/listtype.py (original) +++ pypy/dist/pypy/objspace/std/listtype.py Thu Oct 27 12:23:24 2005 @@ -1,4 +1,5 @@ from __future__ import generators +from pypy.interpreter import gateway from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from sys import maxint @@ -14,7 +15,6 @@ list_sort = StdObjSpaceMultiMethod('sort', 4, defaults=(None, None, False), argnames=['cmp', 'key', 'reverse']) list_reversed = StdObjSpaceMultiMethod('__reversed__', 1) ## -### gateway is imported in the stdtypedef module ##list_reversed__ANY = gateway.applevel(''' ## # NOT_RPYTHON -- uses yield ## Modified: pypy/dist/pypy/objspace/std/objecttype.py ============================================================================== --- pypy/dist/pypy/objspace/std/objecttype.py (original) +++ pypy/dist/pypy/objspace/std/objecttype.py Thu Oct 27 12:23:24 2005 @@ -1,5 +1,6 @@ from pypy.interpreter.error import OperationError from pypy.objspace.descroperation import Object +from pypy.interpreter import gateway from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.register_all import register_all from pypy.objspace.std.objspace import StdObjSpace Modified: pypy/dist/pypy/objspace/std/typetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/typetype.py (original) +++ pypy/dist/pypy/objspace/std/typetype.py Thu Oct 27 12:23:24 2005 @@ -1,4 +1,5 @@ from pypy.interpreter.error import OperationError +from pypy.interpreter import gateway from pypy.objspace.std.stdtypedef import * def descr__new__(space, w_typetype, w_name, w_bases, w_dict): Modified: pypy/dist/pypy/objspace/std/unicodetype.py ============================================================================== --- pypy/dist/pypy/objspace/std/unicodetype.py (original) +++ pypy/dist/pypy/objspace/std/unicodetype.py Thu Oct 27 12:23:24 2005 @@ -1,3 +1,4 @@ +from pypy.interpreter import gateway from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.basestringtype import basestring_typedef from pypy.interpreter.error import OperationError From mwh at codespeak.net Thu Oct 27 12:33:30 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 12:33:30 +0200 (CEST) Subject: [pypy-svn] r19066 - pypy/dist/pypy/annotation Message-ID: <20051027103330.2F82427B83@code1.codespeak.net> Author: mwh Date: Thu Oct 27 12:33:29 2005 New Revision: 19066 Modified: pypy/dist/pypy/annotation/builtin.py Log: remove some unused code Modified: pypy/dist/pypy/annotation/builtin.py ============================================================================== --- pypy/dist/pypy/annotation/builtin.py (original) +++ pypy/dist/pypy/annotation/builtin.py Thu Oct 27 12:33:29 2005 @@ -2,10 +2,9 @@ Built-in functions. """ -import types -import sys, os +import sys from pypy.annotation.model import SomeInteger, SomeObject, SomeChar, SomeBool -from pypy.annotation.model import SomeList, SomeString, SomeTuple, SomeSlice +from pypy.annotation.model import SomeString, SomeTuple, SomeSlice from pypy.annotation.model import SomeUnicodeCodePoint, SomeAddress from pypy.annotation.model import SomeFloat, unionof from pypy.annotation.model import SomePBC, SomeInstance, SomeDict @@ -195,11 +194,6 @@ getbookkeeper().warning("ignoring apply%r" % (stuff,)) return SomeObject() -##def builtin_compile(*stuff): -## s = SomeObject() -## s.knowntype = types.CodeType -## return s - def builtin_slice(*args): bk = getbookkeeper() if len(args) == 1: @@ -279,9 +273,6 @@ def test(*args): return SomeBool() -def pathpart(*args): - return SomeString() - def import_func(*args): return SomeObject() @@ -316,11 +307,6 @@ import unicodedata BUILTIN_ANALYZERS[unicodedata.decimal] = unicodedata_decimal # xxx -# os.path stuff -#BUILTIN_ANALYZERS[os.path.dirname] = pathpart -#BUILTIN_ANALYZERS[os.path.normpath] = pathpart -#BUILTIN_ANALYZERS[os.path.join] = pathpart - # import BUILTIN_ANALYZERS[__import__] = import_func From mwh at codespeak.net Thu Oct 27 12:34:24 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 12:34:24 +0200 (CEST) Subject: [pypy-svn] r19067 - pypy/dist/pypy/annotation Message-ID: <20051027103424.717A427B83@code1.codespeak.net> Author: mwh Date: Thu Oct 27 12:34:23 2005 New Revision: 19067 Modified: pypy/dist/pypy/annotation/bookkeeper.py Log: replace an 'import *' with a semi autogenerated replacement (woo!) Modified: pypy/dist/pypy/annotation/bookkeeper.py ============================================================================== --- pypy/dist/pypy/annotation/bookkeeper.py (original) +++ pypy/dist/pypy/annotation/bookkeeper.py Thu Oct 27 12:34:23 2005 @@ -6,7 +6,12 @@ import sys from types import FunctionType, ClassType, NoneType from pypy.objspace.flow.model import Constant -from pypy.annotation.model import * +from pypy.annotation.model import SomeString, SomeChar, SomeFloat, \ + SomePtr, unionof, SomeInstance, SomeDict, SomeBuiltin, SomePBC, \ + SomeInteger, SomeExternalObject, SomeOOInstance, TLS, SomeAddress, \ + new_or_old_class, SomeUnicodeCodePoint, SomeOOStaticMeth, \ + SomeLLADTMeth, SomeBool, SomeTuple, SomeOOClass, SomeImpossibleValue, \ + SomeList, SomeObject from pypy.annotation.classdef import ClassDef, isclassdef from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF From ericvrp at codespeak.net Thu Oct 27 12:57:55 2005 From: ericvrp at codespeak.net (ericvrp at codespeak.net) Date: Thu, 27 Oct 2005 12:57:55 +0200 (CEST) Subject: [pypy-svn] r19068 - pypy/dist/pypy/translator/js Message-ID: <20051027105755.742F127B83@code1.codespeak.net> Author: ericvrp Date: Thu Oct 27 12:57:54 2005 New Revision: 19068 Modified: pypy/dist/pypy/translator/js/codewriter.py pypy/dist/pypy/translator/js/js.py pypy/dist/pypy/translator/js/opwriter.py Log: Refactoring of indentation_level. No longer hardcoded. Modified: pypy/dist/pypy/translator/js/codewriter.py ============================================================================== --- pypy/dist/pypy/translator/js/codewriter.py (original) +++ pypy/dist/pypy/translator/js/codewriter.py Thu Oct 27 12:57:54 2005 @@ -12,13 +12,28 @@ self.f = f self.js = js self._skip_closeblock = False + self.set_indentation_level(0) def skip_closeblock(self, flag=True): self._skip_closeblock = flag - def append(self, line, indentation_level=4): - if line and indentation_level: - s = self.tabstring * indentation_level + def set_indentation_level(self, indentation_level): + try: + old = self.indentation_level + except: + old = 0 + self.indentation_level = indentation_level + return old + + def indent_more(self): + self.indentation_level += 1 + + def indent_less(self): + self.indentation_level -= 1 + + def append(self, line): + if line and self.indentation_level: + s = self.tabstring * self.indentation_level else: s = '' if not line or line[-1] in '{:};' or line.lstrip()[:2] == '//': @@ -27,43 +42,45 @@ eol = ';\n' self.f.write(s + line + eol) - def comment(self, line, indentation_level=4): - self.append("// " + line, indentation_level) + def comment(self, line): + self.append("// " + line) - def llvm(self, line, indentation_level=4): - self.comment("LLVM " + line, indentation_level) + def llvm(self, line): + self.comment("LLVM " + line) def newline(self): self.append("") def openblock(self, name): - self.append("case %d:" % name, 3) + self.indent_more() + self.append("case %d:" % name) + self.indent_more() self._currentblock = name def closeblock(self): if not self._skip_closeblock: self.append('break') + self.indent_less() + self.indent_less() self.skip_closeblock(False) def globalinstance(self, lines=[]): for line in lines: - self.append(line, 0) + self.append(line) def declare(self, decl): - self.append(decl, 0) + self.append(decl) - def _goto_block(self, block, indentation_level=4): + def _goto_block(self, block): if block == self._currentblock + 1: self._skip_closeblock = True else: - self.append('block = ' + str(block), indentation_level) - self.append('break', indentation_level) + self.append('block = ' + str(block)) + self.append('break') - def _phi(self, targetblock, exit, indentation_level=4): - #self.comment('target.inputargs=%s, args=%s, targetblock=%d' % (exit.target.inputargs, exit.args, targetblock), indentation_level) + def _phi(self, targetblock, exit): for i, exitarg in enumerate(exit.args): dest = str(exit.target.inputargs[i]) - #src = str(exitarg) src = str(self.js.db.repr_arg(exitarg)) if src == 'False': src = 'false' @@ -72,7 +89,7 @@ elif src == 'None': src = 'undefined' if dest != src: - self.append('%s = %s' % (dest, src), indentation_level) + self.append('%s = %s' % (dest, src)) def br_uncond(self, block, exit): self._phi(block, exit) @@ -81,20 +98,24 @@ def br(self, cond, block_false, exit_false, block_true, exit_true): self.append('if (%s) {' % cond) - self._phi(block_true, exit_true, 5) - self._goto_block(block_true, 5) + self.indent_more() + self._phi(block_true, exit_true) + self._goto_block(block_true) + self.indent_less() self.append('} else {') - self._phi(block_false, exit_false, 5) - self._goto_block(block_false, 5) + self.indent_more() + self._phi(block_false, exit_false) + self._goto_block(block_false) + self.indent_less() self.append('}') self.skip_closeblock() - def switch(self, intty, cond, defaultdest, value_label): - labels = '' - for value, label in value_label: - labels += ' %s %s, label %s' % (intty, value, label) - self.llvm("switch %s %s, label %s [%s ]" - % (intty, cond, defaultdest, labels)) + #def switch(self, intty, cond, defaultdest, value_label): + # labels = '' + # for value, label in value_label: + # labels += ' %s %s, label %s' % (intty, value, label) + # self.llvm("switch %s %s, label %s [%s ]" + # % (intty, cond, defaultdest, labels)) def openfunc(self, decl, funcnode, blocks): self.decl = decl @@ -110,16 +131,20 @@ targetvar = self.js.db.repr_arg(op.result) usedvars[targetvar] = True self.newline() - self.append("function %s {" % self.decl, 0) + self.append("function %s {" % self.decl) + self.indent_more() if usedvars: - self.append("var %s" % ', '.join(usedvars.keys()), 1) - self.append("for (var block = 0;;) {", 1) - self.append("switch (block) {", 2) + self.append("var %s" % ', '.join(usedvars.keys())) + self.append("for (var block = 0;;) {") + self.indent_more() + self.append("switch (block) {") def closefunc(self): - self.append("}", 2) - self.append("}", 1) - self.append("};", 0) + self.append("}") + self.indent_less() + self.append("}") + self.indent_less() + self.append("};") def ret(self, ref=''): self.append("return " + ref) @@ -131,30 +156,46 @@ def neg(self, targetvar, source): self.append('%(targetvar)s = -%(source)s' % locals()) - def call(self, targetvar, functionref, argrefs, label=None, exceptions=[], ll_issubclass=None): - if exceptions: - assert label is not None - self.append('try {') - indentation_level = 5 - else: - assert label is None - indentation_level = 4 - + def call(self, targetvar, functionref, argrefs, label=None, exceptions=[]): args = ", ".join(argrefs) - self.append('%s = %s(%s)' % (targetvar, functionref, args), indentation_level) - if exceptions: - self._goto_block(label, indentation_level) + if not exceptions: + assert label is None + self.append('%s = %s(%s)' % (targetvar, functionref, args)) + else: + assert label is not None + self.append('try {') + self.indent_more() + self._goto_block(label) + self.indent_less() + self.append('} catch (e) {') + self.indent_more() + catch_all = False for i, exception in enumerate(exceptions): exception_match, exception_ref, exception_target = exception if i: - s = 'else ' + else_ = 'else ' + else: + else_ = '' + if exception_ref.startswith('structinstance_object_vtable'): + catch_all = True + matcher = '' else: - s = '' - self.append('%sif (%s(e.typeptr, %s) == true) {' % (s, exception_match, exception_ref), indentation_level) - self._goto_block(exception_target, indentation_level+1) - self.append('}', indentation_level) + matcher = 'if (%s(e.typeptr, %s) == true) ' % (exception_match, exception_ref) + self.append('%s%s{' % (else_, matcher)) + self.indent_more() + self._goto_block(exception_target) + self.indent_less() + self.append('}') + if not catch_all: + self.append('else {') + self.indent_more() + self.throw('e') #reraise exception when not caught above + self.indent_less() + self.append('}') + + self.indent_less() self.append('}') def cast(self, targetvar, fromtype, fromvar, targettype): Modified: pypy/dist/pypy/translator/js/js.py ============================================================================== --- pypy/dist/pypy/translator/js/js.py (original) +++ pypy/dist/pypy/translator/js/js.py Thu Oct 27 12:57:54 2005 @@ -45,7 +45,7 @@ c = inputconst(lltype.typeOf(ptr), ptr) self.db.prepare_arg_value(c) - #add functions + #add exception matching function (XXX should only be done when needed) e = self.db.translator.rtyper.getexceptiondata() matchptr = getfunctionptr(self.db.translator, e.ll_exception_match) matchconst = inputconst(lltype.typeOf(matchptr), matchptr) @@ -141,7 +141,7 @@ #codewriter.newline() #codewriter.append(self.wrappercode, 0) codewriter.newline() - codewriter.comment("EOF", 0) + codewriter.comment("EOF") f.close() log('Written:', self.filename) Modified: pypy/dist/pypy/translator/js/opwriter.py ============================================================================== --- pypy/dist/pypy/translator/js/opwriter.py (original) +++ pypy/dist/pypy/translator/js/opwriter.py Thu Oct 27 12:57:54 2005 @@ -282,72 +282,6 @@ exceptions.append(exception) self.codewriter.call(targetvar, functionref, argrefs, none_label, exceptions) - return - - - - - e = self.db.translator.rtyper.getexceptiondata() - pypy_prefix = '' #pypy_ - ll_exception_match = pypy_prefix + e.ll_exception_match.__name__ - 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.openblock(exc_label) - - exc_found_labels, last_exception_type = [], None - catch_all = False - 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() - target = self.node.blockindex[link.target] - #exc_found_label = block_label + '_exception_found_branchto_' + target - exc_found_label = target #'%d_exception_found_branchto_%d' % (block_label, target) - last_exc_type_var, last_exc_value_var = None, None - - #XXX refactor this - #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 - # 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 = str(block_label) + '_not_exception_' + etype.ref[1:] - - if current_exception_type.find('getelementptr') == -1: #catch all (except:) - catch_all = True - self.codewriter.comment('br_uncond %s' % exc_found_label) - #self.codewriter.br_uncond(exc_found_label) - else: #catch specific exception (class) type - if not last_exception_type: #load pointer only once - 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, - 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.openblock(not_this_exception_label) - - ep = self.codewriter.js.exceptionpolicy - if not catch_all: - ep.reraise(self.node, self.codewriter) - ep.fetch_exceptions(self.codewriter,self.block,exc_found_labels,lltype_of_exception_type,lltype_of_exception_value) def malloc(self, op): arg_type = op.args[0].value From mwh at codespeak.net Thu Oct 27 14:56:31 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 14:56:31 +0200 (CEST) Subject: [pypy-svn] r19072 - pypy/dist/pypy/objspace/std Message-ID: <20051027125631.3F69227B83@code1.codespeak.net> Author: mwh Date: Thu Oct 27 14:56:30 2005 New Revision: 19072 Modified: pypy/dist/pypy/objspace/std/fake.py Log: repair import mistake, move all imports to top. Modified: pypy/dist/pypy/objspace/std/fake.py ============================================================================== --- pypy/dist/pypy/objspace/std/fake.py (original) +++ pypy/dist/pypy/objspace/std/fake.py Thu Oct 27 14:56:30 2005 @@ -4,6 +4,9 @@ from pypy.interpreter.function import Function, BuiltinFunction from pypy.objspace.std.stdtypedef import * from pypy.objspace.std.model import W_Object, UnwrapError +from pypy.interpreter.baseobjspace import Wrappable +from pypy.interpreter.typedef import TypeDef +from pypy.interpreter import gateway, argument # this file automatically generates non-reimplementations of CPython # types that we do not yet implement in the standard object space @@ -189,11 +192,6 @@ _fake_type_cache[type(list.append)] = fake_builtin_callable _fake_type_cache[type(type(None).__repr__)] = fake_builtin_callable - -from pypy.interpreter.baseobjspace import Wrappable -from pypy.interpreter.typedef import TypeDef -from pypy.interpreter import gateway, argument - class W_FakeDescriptor(Wrappable): # Mimics pypy.interpreter.typedef.GetSetProperty. @@ -236,14 +234,14 @@ W_FakeDescriptor.typedef = TypeDef( "FakeDescriptor", - __get__ = interp2app(W_FakeDescriptor.descr_descriptor_get.im_func, + __get__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_get.im_func, unwrap_spec = [baseobjspace.ObjSpace, W_FakeDescriptor, baseobjspace.W_Root, baseobjspace.W_Root]), - __set__ = interp2app(W_FakeDescriptor.descr_descriptor_set.im_func, + __set__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_set.im_func, unwrap_spec = [baseobjspace.ObjSpace, W_FakeDescriptor, baseobjspace.W_Root, baseobjspace.W_Root]), - __delete__ = interp2app(W_FakeDescriptor.descr_descriptor_del.im_func, + __delete__ = gateway.interp2app(W_FakeDescriptor.descr_descriptor_del.im_func, unwrap_spec = [baseobjspace.ObjSpace, W_FakeDescriptor, baseobjspace.W_Root]), ) From mwh at codespeak.net Thu Oct 27 15:06:00 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 15:06:00 +0200 (CEST) Subject: [pypy-svn] r19074 - pypy/dist/pypy/doc/weekly Message-ID: <20051027130600.BAD6C27B83@code1.codespeak.net> Author: mwh Date: Thu Oct 27 15:05:58 2005 New Revision: 19074 Added: pypy/dist/pypy/doc/weekly/ pypy/dist/pypy/doc/weekly/index.txt (contents, props changed) pypy/dist/pypy/doc/weekly/log (contents, props changed) Log: stuff for 'this week in pypy' -- see mail on pypy-dev soon-ish Added: pypy/dist/pypy/doc/weekly/index.txt ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/weekly/index.txt Thu Oct 27 15:05:58 2005 @@ -0,0 +1,22 @@ +"This week in PyPy" stuff +------------------------- + +I (mwh) am going to write a summary of what's been happening in +pypy-land each week. To help me along, please add (append) things +worth mentioning to the file ``log`` in this directory. + +To be most helpful, please say who you are, roughly when you're adding +things and mention where in the #pypy logs relavent discussion can be +found. For example:: + + 2005-10-27 mwh + + I decided to write "This week in PyPy" each week! See + http://tismerysoft.de/pypy/irc-logs/pypy/%23pypy.log.20051027 + around 13:30 server time. + +Once a week (probably after the Thursday lunchtime pypy-sync meeting) +I'll run through the file, write up the the best bits, send that to +pypy-dev, copy the log file to log.YEAR-MONTH-DAY and make a new one. + +Thanks in advance! Added: pypy/dist/pypy/doc/weekly/log ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/weekly/log Thu Oct 27 15:05:58 2005 @@ -0,0 +1,6 @@ +2005-10-27 mwh + + I decided to write "This week in PyPy" each week! See + http://tismerysoft.de/pypy/irc-logs/pypy/%23pypy.log.20051027 + around 13:30 server time. + From mwh at codespeak.net Thu Oct 27 15:12:45 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 15:12:45 +0200 (CEST) Subject: [pypy-svn] r19076 - pypy/dist/pypy/doc/weekly Message-ID: <20051027131245.6BB2C27B8E@code1.codespeak.net> Author: mwh Date: Thu Oct 27 15:12:44 2005 New Revision: 19076 Added: pypy/dist/pypy/doc/weekly/style.css Log: maybe adding this Added: pypy/dist/pypy/doc/weekly/style.css ============================================================================== --- (empty file) +++ pypy/dist/pypy/doc/weekly/style.css Thu Oct 27 15:12:44 2005 @@ -0,0 +1,1083 @@ +body,body.editor,body.body { + font: 110% "Times New Roman", Arial, Verdana, Helvetica, serif; + background: White; + color: Black; +} + +a, a.reference { + text-decoration: none; +} +a[href]:hover { text-decoration: underline; } + +img { + border: none; + vertical-align: middle; +} + +p, div.text { + text-align: left; + line-height: 1.5em; + margin: 0.5em 0em 0em 0em; +} + + + +p a:active { + color: Red; + background-color: transparent; +} + +p img { + border: 0; + margin: 0; +} + +img.inlinephoto { + padding: 0; + padding-right: 1em; + padding-top: 0.7em; + float: left; +} + +hr { + clear: both; + height: 1px; + color: #8CACBB; + background-color: transparent; +} + + +ul { + line-height: 1.5em; + /*list-style-image: url("bullet.gif"); */ + margin-left: 1.5em; + padding:0; +} + +ol { + line-height: 1.5em; + margin-left: 1.5em; + padding:0; +} + +ul a, ol a { + text-decoration: underline; +} + +dl { +} + +dt { + font-weight: bold; +} + +dd { + line-height: 1.5em; + margin-bottom: 1em; +} + +blockquote { + font-family: Times, "Times New Roman", serif; + font-style: italic; + font-size: 120%; +} + +code { + color: Black; + /*background-color: #dee7ec;*/ + background-color: #cccccc; +} + +pre { + padding: 1em; + border: 1px solid #8cacbb; + color: Black; + background-color: #dee7ec; + background-color: #cccccc; + overflow: auto; +} + + +.netscape4 { + display: none; +} + +/* main page styles */ + +/*a[href]:hover { color: black; text-decoration: underline; } +a[href]:link { color: black; text-decoration: underline; } +a[href] { color: black; text-decoration: underline; } +*/ + +span.menu_selected { + color: black; + font: 120% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; + padding-right: 0.3em; + background-color: #cccccc; +} + + +a.menu { + /*color: #3ba6ec; */ + font: 120% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; + padding-right: 0.3em; +} + +a.menu[href]:visited, a.menu[href]:link{ + /*color: #3ba6ec; */ + font: 120% Verdana, Helvetica, Arial, sans-serif; + text-decoration: none; +} + +a.menu[href]:hover { + /*color: black;*/ +} + +div.project_title{ + /*border-spacing: 20px;*/ + font: 160% Verdana, Helvetica, Arial, sans-serif; + color: #3ba6ec; + vertical-align: center; + padding-bottom: 0.3em; +} + +a.wikicurrent { + font: 100% Verdana, Helvetica, Arial, sans-serif; + color: #3ba6ec; + vertical-align: middle; +} + + +table.body { + border: 0; + /*padding: 0; + border-spacing: 0px; + border-collapse: separate; + */ +} + +td.page-header-left { + padding: 5px; + /*border-bottom: 1px solid #444444;*/ +} + +td.page-header-top { + padding: 0; + + /*border-bottom: 1px solid #444444;*/ +} + +td.sidebar { + padding: 1 0 0 1; +} + +td.sidebar p.classblock { + padding: 0 5 0 5; + margin: 1 1 1 1; + border: 1px solid #444444; + background-color: #eeeeee; +} + +td.sidebar p.userblock { + padding: 0 5 0 5; + margin: 1 1 1 1; + border: 1px solid #444444; + background-color: #eeeeff; +} + +td.content { + padding: 1 5 1 5; + vertical-align: top; + width: 100%; +} + +p.ok-message { + background-color: #22bb22; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} +p.error-message { + background-color: #bb2222; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} + +p:first-child { + margin: 0 ; + padding: 0; +} + +/* style for forms */ +table.form { + padding: 2; + border-spacing: 0px; + border-collapse: separate; +} + +table.form th { + color: #333388; + text-align: right; + vertical-align: top; + font-weight: normal; +} +table.form th.header { + font-weight: bold; + background-color: #eeeeff; + text-align: left; +} + +table.form th.required { + font-weight: bold; +} + +table.form td { + color: #333333; + empty-cells: show; + vertical-align: top; +} + +table.form td.optional { + font-weight: bold; + font-style: italic; +} + +table.form td.html { + color: #777777; +} + +/* style for lists */ +table.list { + border-spacing: 0px; + border-collapse: separate; + vertical-align: top; + padding-top: 0; + width: 100%; +} + +table.list th { + padding: 0 4 0 4; + color: #404070; + background-color: #eeeeff; + border-right: 1px solid #404070; + border-top: 1px solid #404070; + border-bottom: 1px solid #404070; + vertical-align: top; + empty-cells: show; +} +table.list th a[href]:hover { color: #404070 } +table.list th a[href]:link { color: #404070 } +table.list th a[href] { color: #404070 } +table.list th.group { + background-color: #f4f4ff; + text-align: center; + font-size: 120%; +} + +table.list td { + padding: 0 4 0 4; + border: 0 2 0 2; + border-right: 1px solid #404070; + color: #404070; + background-color: white; + vertical-align: top; + empty-cells: show; +} + +table.list tr.normal td { + background-color: white; + white-space: nowrap; +} + +table.list tr.alt td { + background-color: #efefef; + white-space: nowrap; +} + +table.list td:first-child { + border-left: 1px solid #404070; + border-right: 1px solid #404070; +} + +table.list th:first-child { + border-left: 1px solid #404070; + border-right: 1px solid #404070; +} + +table.list tr.navigation th { + text-align: right; +} +table.list tr.navigation th:first-child { + border-right: none; + text-align: left; +} + + +/* style for message displays */ +table.messages { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.messages th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.messages th { + font-weight: bold; + color: black; + text-align: left; + border-bottom: 1px solid #afafaf; +} + +table.messages td { + font-family: monospace; + background-color: #efefef; + border-bottom: 1px solid #afafaf; + color: black; + empty-cells: show; + border-right: 1px solid #afafaf; + vertical-align: top; + padding: 2 5 2 5; +} + +table.messages td:first-child { + border-left: 1px solid #afafaf; + border-right: 1px solid #afafaf; +} + +/* style for file displays */ +table.files { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.files th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.files th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; +} + +table.files td { + font-family: monospace; + empty-cells: show; +} + +/* style for history displays */ +table.history { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.history th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; + font-size: 100%; +} + +table.history th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; + font-size: 90%; +} + +table.history td { + font-size: 90%; + vertical-align: top; + empty-cells: show; +} + + +/* style for class list */ +table.classlist { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.classlist th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.classlist th { + font-weight: bold; + text-align: left; +} + + +/* style for class help display */ +table.classhelp { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.classhelp th { + font-weight: bold; + text-align: left; + color: #707040; +} + +table.classhelp td { + padding: 2 2 2 2; + border: 1px solid black; + text-align: left; + vertical-align: top; + empty-cells: show; +} + + +/* style for "other" displays */ +table.otherinfo { + border-spacing: 0px; + border-collapse: separate; + width: 100%; +} + +table.otherinfo th.header{ + padding-top: 10px; + border-bottom: 1px solid gray; + font-weight: bold; + background-color: white; + color: #707040; +} + +table.otherinfo th { + border-bottom: 1px solid #afafaf; + font-weight: bold; + text-align: left; +} + +input { + border: 1px solid #8cacbb; + color: Black; + background-color: white; + vertical-align: middle; + margin-bottom: 1px; /* IE bug fix */ + padding: 0.1em; +} + +select { + border: 1px solid #8cacbb; + color: Black; + background-color: white; + vertical-align: middle; + margin-bottom: 1px; /* IE bug fix */ + padding: 0.1em; +} + + +a.nonexistent { + color: #FF2222; +} +a.nonexistent:visited { + color: #FF2222; +} +a.external { + color: #AA6600; +} + +/* +dl,ul,ol { + margin-top: 1pt; +} +tt,pre { + font-family: Lucida Console,Courier New,Courier,monotype; + font-size: 12pt; +} +pre.code { + margin-top: 8pt; + margin-bottom: 8pt; + background-color: #FFFFEE; + white-space:pre; + border-style:solid; + border-width:1pt; + border-color:#999999; + color:#111111; + padding:5px; + width:100%; +} +*/ +div.diffold { + background-color: #FFFF80; + border-style:none; + border-width:thin; + width:100%; +} +div.diffnew { + background-color: #80FF80; + border-style:none; + border-width:thin; + width:100%; +} +div.message { + margin-top: 6pt; + background-color: #E8FFE8; + border-style:solid; + border-width:1pt; + border-color:#999999; + color:#440000; + padding:5px; + width:100%; +} +strong.highlight { + background-color: #FFBBBB; +/* as usual, NetScape fucks up with innocent CSS + border-color: #FFAAAA; + border-style: solid; + border-width: 1pt; +*/ +} + +table.navibar { + background-color: #C8C8C8; + border-spacing: 3px; +} +td.navibar { + background-color: #E8E8E8; + vertical-align: top; + text-align: right; + padding: 0px; +} + +div.pagename { + font-size: 140%; + color: blue; + text-align: center; + font-weight: bold; + background-color: white; + padding: 0 ; +} + +a.wikiaction, input.wikiaction { + color: black; + text-decoration: None; + text-align: center; + color: black; + /*border: 1px solid #3ba6ec; */ + margin: 4px; + padding: 5; + padding-bottom: 0; + white-space: nowrap; +} + +a.wikiaction[href]:hover { + color: black; + text-decoration: none; + /*background-color: #dddddd; */ +} + +span.wikiuserpref { + padding-top: 1em; + font-size: 120%; +} + +div.wikitrail { + vertical-align: bottom; + /*font-size: -1;*/ + padding-top: 1em; + display: none; +} + +div.wikiaction { + vertical-align: middle; + /*border-bottom: 1px solid #8cacbb;*/ + padding-bottom:1em; + text-align: left; + width: 100%; +} + +div.wikieditmenu { + text-align: right; +} + +form.wikiedit { + border: 1px solid #8cacbb; + background-color: #f0f0f0; + background-color: #fabf00; + padding: 1em; + padding-right: 0em; +} + +div.legenditem { + padding-top: 0.5em; + padding-left: 0.3em; +} + +span.wikitoken { + background-color: #eeeeee; +} + + +div#contentspace h1:first-child, div.heading:first-child { + padding-top: 0; + margin-top: 0; +} +div#contentspace h2:first-child { + padding-top: 0; + margin-top: 0; +} + +/* heading and paragraph text */ + +div.heading, h1 { + font-family: Verdana, Helvetica, Arial, sans-serif; + background-color: #58b3ef; + background-color: #FFFFFF; + /*color: #4893cf;*/ + color: black; + padding-top: 1.0em; + padding-bottom:0.2em; + text-align: left; + margin-top: 0em; + /*margin-bottom:8pt;*/ + font-weight: bold; + font-size: 115%; + border-bottom: 1px solid #8CACBB; +} + + +h1, h2, h3, h4, h5, h6 { + color: Black; + clear: left; + font: 100% Verdana, Helvetica, Arial, sans-serif; + margin: 0; + padding-left: 0em; + padding-top: 1em; + padding-bottom: 0.2em; + /*border-bottom: 1px solid #8CACBB;*/ +} +/* h1,h2 { padding-top: 0; }*/ + + +h1 { font-size: 145%; } +h2 { font-size: 135%; } +h3 { font-size: 125%; } +h4 { font-size: 120%; } +h5 { font-size: 110%; } +h6 { font-size: 80%; } + +h1 a { text-decoration: None;} + +div.exception { + background-color: #bb2222; + padding: 5 5 5 5; + color: white; + font-weight: bold; +} +pre.exception { + font-size: 110%; + padding: 1em; + border: 1px solid #8cacbb; + color: Black; + background-color: #dee7ec; + background-color: #cccccc; +} + +/* defines for navgiation bar (documentation) */ + + +div.direntry { + padding-top: 0.3em; + padding-bottom: 0.3em; + margin-right: 1em; + font-weight: bold; + background-color: #dee7ec; + font-size: 110%; +} + +div.fileentry { + font-family: Verdana, Helvetica, Arial, sans-serif; + padding-bottom: 0.3em; + white-space: nowrap; + line-height: 150%; +} + +a.fileentry { + white-space: nowrap; +} + + +span.left { + text-align: left; +} +span.right { + text-align: right; +} + +div.navbar { + /*margin: 0;*/ + font-size: 80% /*smaller*/; + font-weight: bold; + text-align: left; + /* position: fixed; */ + top: 100pt; + left: 0pt; /* auto; */ + width: 120pt; + /* right: auto; + right: 0pt; 2em; */ +} + + +div.history a { + /* font-size: 70%; */ +} + +div.wikiactiontitle { + font-weight: bold; +} + +/* REST defines */ + +div.document { + margin: 0; +} + +h1.title { + margin: 0; +} + +td.toplist { + vertical-align: top; +} + +img#pyimg { + position: absolute; + top: 4px; + left: 4px; +} + +img#extraimg { + position: absolute; + right: 14px; + top: 4px; +} + +div#navspace { + position: absolute; + top: 130px; + left: 11px; + font-size: 100%; + width: 150px; + overflow: hidden; /* scroll; */ +} + +div#metaspace { + position: absolute; + top: 40px; + left: 170px; +} + +div#errorline { + position: relative; + top: 5px; + float: right; +} + +div#contentspace { + position: absolute; + /* font: 120% "Times New Roman", serif;*/ + font: 110% Verdana, Helvetica, Arial, sans-serif; + top: 130px; + left: 170px; + margin-right: 5px; +} + +div#menubar { +/* width: 400px; */ + float: left; +} + +/* for the documentation page */ +div#docinfoline { + position: relative; + top: 5px; + left: 0px; + + /*background-color: #dee7ec; */ + padding: 5pt; + padding-bottom: 1em; + color: black; + /*border-width: 1pt; + border-style: solid;*/ + +} + +div#docnavlist { + /*background-color: #dee7ec; */ + padding: 5pt; + padding-bottom: 2em; + color: black; + border-width: 1pt; + /*border-style: solid;*/ +} + + +/* text markup */ + +div.listtitle { + color: Black; + clear: left; + font: 120% Verdana, Helvetica, Arial, sans-serif; + margin: 0; + padding-left: 0em; + padding-top: 0em; + padding-bottom: 0.2em; + margin-right: 0.5em; + border-bottom: 1px solid #8CACBB; +} + +div.actionbox h3 { + padding-top: 0; + padding-right: 0.5em; + padding-left: 0.5em; + background-color: #fabf00; + text-align: center; + border: 1px solid black; /* 8cacbb; */ +} + +div.actionbox a { + display: block; + padding-bottom: 0.5em; + padding-top: 0.5em; + margin-left: 0.5em; +} + +div.actionbox a.history { + display: block; + padding-bottom: 0.5em; + padding-top: 0.5em; + margin-left: 0.5em; + font-size: 90%; +} + +div.actionbox { + margin-bottom: 2em; + padding-bottom: 1em; + overflow: hidden; /* scroll; */ +} + +/* taken from docutils (oh dear, a bit senseless) */ +ol.simple, ul.simple { + margin-bottom: 1em } + +ol.arabic { + list-style: decimal } + +ol.loweralpha { + list-style: lower-alpha } + +ol.upperalpha { + list-style: upper-alpha } + +ol.lowerroman { + list-style: lower-roman } + +ol.upperroman { + list-style: upper-roman } + + +/* +:Author: David Goodger +:Contact: goodger at users.sourceforge.net +:date: $Date: 2003/01/22 22:26:48 $ +:version: $Revision: 1.29 $ +:copyright: This stylesheet has been placed in the public domain. + +Default cascading style sheet for the HTML output of Docutils. +*/ +/* +.first { + margin-top: 0 } + +.last { + margin-bottom: 0 } + +a.toc-backref { + text-decoration: none ; + color: black } + +dd { + margin-bottom: 0.5em } + +div.abstract { + margin: 2em 5em } + +div.abstract p.topic-title { + font-weight: bold ; + text-align: center } + +div.attention, div.caution, div.danger, div.error, div.hint, +div.important, div.note, div.tip, div.warning { + margin: 2em ; + border: medium outset ; + padding: 1em } + +div.attention p.admonition-title, div.caution p.admonition-title, +div.danger p.admonition-title, div.error p.admonition-title, +div.warning p.admonition-title { + color: red ; + font-weight: bold ; + font-family: sans-serif } + +div.hint p.admonition-title, div.important p.admonition-title, +div.note p.admonition-title, div.tip p.admonition-title { + font-weight: bold ; + font-family: sans-serif } + +div.dedication { + margin: 2em 5em ; + text-align: center ; + font-style: italic } + +div.dedication p.topic-title { + font-weight: bold ; + font-style: normal } + +div.figure { + margin-left: 2em } + +div.footer, div.header { + font-size: smaller } + +div.system-messages { + margin: 5em } + +div.system-messages h1 { + color: red } + +div.system-message { + border: medium outset ; + padding: 1em } + +div.system-message p.system-message-title { + color: red ; + font-weight: bold } + +div.topic { + margin: 2em } + +h1.title { + text-align: center } + +h2.subtitle { + text-align: center } + +hr { + width: 75% } + +p.caption { + font-style: italic } + +p.credits { + font-style: italic ; + font-size: smaller } + +p.label { + white-space: nowrap } + +p.topic-title { + font-weight: bold } + +pre.address { + margin-bottom: 0 ; + margin-top: 0 ; + font-family: serif ; + font-size: 100% } + +pre.line-block { + font-family: serif ; + font-size: 100% } + +pre.literal-block, pre.doctest-block { + margin-left: 2em ; + margin-right: 2em ; + background-color: #eeeeee } + +span.classifier { + font-family: sans-serif ; + font-style: oblique } + +span.classifier-delimiter { + font-family: sans-serif ; + font-weight: bold } + +span.interpreted { + font-family: sans-serif } + +span.option { + white-space: nowrap } + +span.option-argument { + font-style: italic } + +span.pre { + white-space: pre } + +span.problematic { + color: red } + +table { + margin-top: 0.5em ; + margin-bottom: 0.5em } + +table.citation { + border-left: solid thin gray ; + padding-left: 0.5ex } + +table.docinfo { + margin: 2em 4em } + +table.footnote { + border-left: solid thin black ; + padding-left: 0.5ex } + +td, th { + padding-left: 0.5em ; + padding-right: 0.5em ; + vertical-align: top } + +th.docinfo-name, th.field-name { + font-weight: bold ; + text-align: left ; + white-space: nowrap } + +h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { + font-size: 100% } + +tt { + background-color: #eeeeee } + +ul.auto-toc { + list-style-type: none } +*/ + +div.section { + margin-top: 1.0em ; +} From mwh at codespeak.net Thu Oct 27 15:13:14 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 15:13:14 +0200 (CEST) Subject: [pypy-svn] r19077 - pypy/dist/pypy/doc/weekly Message-ID: <20051027131314.9C34727B92@code1.codespeak.net> Author: mwh Date: Thu Oct 27 15:13:13 2005 New Revision: 19077 Removed: pypy/dist/pypy/doc/weekly/style.css Log: argh, meant to abort that commit.. From mwh at codespeak.net Thu Oct 27 15:13:47 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 15:13:47 +0200 (CEST) Subject: [pypy-svn] r19078 - pypy/dist/pypy/doc/weekly Message-ID: <20051027131347.3BA3A27B94@code1.codespeak.net> Author: mwh Date: Thu Oct 27 15:13:46 2005 New Revision: 19078 Added: pypy/dist/pypy/doc/weekly/style.css - copied unchanged from r19047, pypy/dist/pypy/doc/style.css Log: maybe adding this here will help weekly/index.html look right? From pedronis at codespeak.net Thu Oct 27 15:23:48 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Thu, 27 Oct 2005 15:23:48 +0200 (CEST) Subject: [pypy-svn] r19083 - pypy/dist/pypy/translator/c/test Message-ID: <20051027132348.6DA0E27B6E@code1.codespeak.net> Author: pedronis Date: Thu Oct 27 15:23:47 2005 New Revision: 19083 Modified: pypy/dist/pypy/translator/c/test/test_stackless.py Log: argv should be forced var-sized Modified: pypy/dist/pypy/translator/c/test/test_stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_stackless.py (original) +++ pypy/dist/pypy/translator/c/test/test_stackless.py Thu Oct 27 15:23:47 2005 @@ -13,6 +13,7 @@ t = Translator(entry_point) s_list_of_strings = SomeList(ListDef(None, SomeString())) + s_list_of_strings.listdef.resize() ann = t.annotate([s_list_of_strings]) t.specialize() cbuilder = t.cbuilder(standalone=True) From mwh at codespeak.net Thu Oct 27 15:29:36 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 15:29:36 +0200 (CEST) Subject: [pypy-svn] r19084 - pypy/dist/pypy/doc/weekly Message-ID: <20051027132936.E4B1227B6E@code1.codespeak.net> Author: mwh Date: Thu Oct 27 15:29:35 2005 New Revision: 19084 Added: pypy/dist/pypy/doc/weekly/confrest.py - copied, changed from r19047, pypy/dist/pypy/doc/confrest.py Log: add a hacked confrest to make the menu links work. From cfbolz at codespeak.net Thu Oct 27 20:21:57 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Oct 2005 20:21:57 +0200 (CEST) Subject: [pypy-svn] r19094 - pypy/dist/pypy/module/recparser/compiler Message-ID: <20051027182157.1045D27B6C@code1.codespeak.net> Author: cfbolz Date: Thu Oct 27 20:21:56 2005 New Revision: 19094 Removed: pypy/dist/pypy/module/recparser/compiler/ Log: one more unneeded compiler package removed. I am note sure whether it really is unneeded but all tests pass. It's all Michael's fault anyway :-) From mwh at codespeak.net Thu Oct 27 20:47:42 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Thu, 27 Oct 2005 20:47:42 +0200 (CEST) Subject: [pypy-svn] r19096 - pypy/dist/pypy/doc Message-ID: <20051027184742.49F7527B6E@code1.codespeak.net> Author: mwh Date: Thu Oct 27 20:47:41 2005 New Revision: 19096 Modified: pypy/dist/pypy/doc/draft-low-level-encapsulation.txt Log: wording Modified: pypy/dist/pypy/doc/draft-low-level-encapsulation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-low-level-encapsulation.txt (original) +++ pypy/dist/pypy/doc/draft-low-level-encapsulation.txt Thu Oct 27 20:47:41 2005 @@ -45,7 +45,7 @@ CPython but this was not done partly because the code that fully enabled stackless required widespread modifications that made the code harder to understand (as the "stackless" model contains control flow that is not -naturally expressable in C, the implementation became much less +easily expressable in C, the implementation became much less "natural" in some sense). With PyPy, however, it is possible to obtain this flexible control flow From cfbolz at codespeak.net Thu Oct 27 22:29:07 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Oct 2005 22:29:07 +0200 (CEST) Subject: [pypy-svn] r19097 - pypy/extradoc/minute Message-ID: <20051027202907.E621C27B90@code1.codespeak.net> Author: cfbolz Date: Thu Oct 27 22:29:06 2005 New Revision: 19097 Added: pypy/extradoc/minute/pypy-sync-10-27.txt Log: minutes pypy-sync meeting Added: pypy/extradoc/minute/pypy-sync-10-27.txt ============================================================================== --- (empty file) +++ pypy/extradoc/minute/pypy-sync-10-27.txt Thu Oct 27 22:29:06 2005 @@ -0,0 +1,307 @@ +============================================= +pypy-sync developer meeting 20th October +============================================= + +Time & location: 1pm (30 minutes) at #pypy-sync + +Attendees:: + + Samuele Pedroni + Armin Rigo (left early) + Holger Krekel + Eric van Riet Paap + Michael Hudson + Carl Friedrich Bolz + Bert Freudenberg + + +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 blockers + +Topics of the week +=================== + +"this week on #pypy" +-------------------------- + +Michael volunteered to write a short "This week in pypy-land" text every week +(which would include the events in #pypy and other interesting stuff). This +would make e.g. navigating the #pypy-logs a lot easier but is also quite a lot +of work. Holger suggested that we should have a file in svn where everybody can +insert paragraphs. This was considered a good ideal. Michael plans to summarize +everything at the end of the week and send mails to pypy-dev. + + +new release +-------------------------- + +Samuele brought up the issue of another making another release (0.8.0) soon +that highlights the translatable parser/compiler. He wants this because some +of the reportwriting he has to do is blocked by the fact that this release did +not happen yet. The features of the release would be working/translatable +astcompiler, translatable thunk object space, cleaned up translate_pypy and a +bit more speed. + +The idea was to try make a small release that should not take too much work. +One of the biggest problems is that Holger is not really avaiable next week +which is when Samuele planned to do the release. Holger did a lot of the +infrastructure work for the last releases. Samuele noted that this release is a +bit different since we don't have new features that we want to rush in in the +last minute. It was decided that we should try to make a release friday next +week (November 4th, 2005), making a release branch on October, 28th. Over the +weekend the compliancy tests will be run to see whether compliancy got worse. +If this is the case we might have to reconsider. On Monday (October, 31th) +there will be a planning meeting. All in all there don't seem to be that many +people avaiable for the release: Samuele, Michael, Anders L., Arre(?), Carl +Friedrich (maybe a little), Christian (a bit). + + +gothenburg sprint topics +-------------------------- + +topic deferred to next pypy-sync. + + +Complete IRC log +================= + +complete log:: + + **** BEGIN LOGGING AT Thu Oct 27 12:58:02 2005 + + Oct 27 12:58:02 * Now talking on #pypy-sync + Oct 27 12:58:18 * hpk (n=hpk at adsl-236-175-192-81.adsl2.iam.net.ma) has joined #pypy-sync + Oct 27 13:00:29 cfbolz hi all! + Oct 27 13:00:34 hpk hi! + Oct 27 13:00:38 cfbolz it's 1 on my clock, so shall we start? + Oct 27 13:00:55 hpk fine for me. let's see if some others are awake :) + Oct 27 13:01:02 cfbolz :-) + Oct 27 13:01:02 pedronis hi, yes + Oct 27 13:01:05 mwh hello + Oct 27 13:01:06 arigo hi! + Oct 27 13:01:36 cfbolz ok, everybody post their activity reports! + Oct 27 13:01:39 ericvrp hi~ + Oct 27 13:01:48 arigo LAST: holidays + reports + a stackless RPython interface + Oct 27 13:01:48 arigo NEXT: holidays + finish report draft-dynamic-etc + choose new laptop + Oct 27 13:01:48 arigo BLOCKERS: - + Oct 27 13:01:58 ericvrp Last: some genjs, mostly non-PyPy + Oct 27 13:01:59 ericvrp Next: dito + Oct 27 13:02:01 ericvrp Blockers: - + Oct 27 13:02:09 cfbolz LAST: statistic gathering, pypy unrelated + Oct 27 13:02:09 cfbolz NEXT: report + Oct 27 13:02:09 cfbolz BLOCKERS: none + Oct 27 13:02:27 hpk LAST: eu dissemniation/talk planning, codespeak admin. NEXT: pycon proposals, finalizing dissemination planning. BLOCKERS: somewhat non-permanent internet connection + Oct 27 13:02:46 pedronis LAST: some release prep, D04.4, looked at other reports, some other rep writing,rtyper level opts/code reductions + Oct 27 13:02:48 pedronis NEXT: release, finish D04.4, help with other reports + Oct 27 13:02:49 pedronis BLOCKERS: - + Oct 27 13:03:37 mwh last week: got a job! making and using refactoring tools + Oct 27 13:03:37 mwh next week: more of same + Oct 27 13:03:37 mwh blockers: - + Oct 27 13:04:14 mwh oh, and pycon proposals for next week + Oct 27 13:04:17 * aleale (n=andersle at clogs.dfki.uni-sb.de) has joined #pypy-sync + Oct 27 13:04:20 hpk bertf: ? + Oct 27 13:04:39 cfbolz aleale: your activity report? + Oct 27 13:04:42 aleale PREV: Writing report + Oct 27 13:04:54 aleale NEXT: WP9 + Oct 27 13:05:00 aleale BLockers:- + Oct 27 13:05:11 bertf LAST: following svn activities NEXT: report BLOCKERS: - + Oct 27 13:05:31 cfbolz ok, let's proceed then to the regular topics + Oct 27 13:05:36 cfbolz there don't seem to be blockers + Oct 27 13:05:39 cfbolz "this week on #pypy" + Oct 27 13:05:39 cfbolz -------------------------- + Oct 27 13:06:05 cfbolz michael volunteered to write something weekly about the ongoings of #pypy but would like to be notified about interesting stuff + Oct 27 13:06:38 hpk probably makes sense to have a weekly svn-commit file where people can insert paras? + Oct 27 13:07:01 mwh that makes sense so long as people actually do it :) + Oct 27 13:07:10 cfbolz indeed. and I fear they don't :-) + Oct 27 13:07:21 hpk well, all things need a bit of time to establish + Oct 27 13:07:25 mwh but yes, let's keep an activity log in svn + Oct 27 13:07:37 hpk but offering a structure makes it easier and point people to it + Oct 27 13:07:43 mwh and basically i'll summarize it and send it to pypy-dev each week + Oct 27 13:07:46 hpk should theey complain that a particular topic wasn't included + Oct 27 13:07:56 cfbolz makes sense + Oct 27 13:08:00 mwh i'll probably mostly maintain it as well to start with + Oct 27 13:08:42 * stakkars (n=tismer at ip-80-226-246-109.vodafone-net.de) has joined #pypy-sync + Oct 27 13:08:43 mwh extradoc/weekly or something? + Oct 27 13:08:51 cfbolz sounds good! + Oct 27 13:08:54 hpk mwh: yes, irc-weekly maybe + Oct 27 13:09:06 cfbolz does that approach make sense for everybody? + Oct 27 13:09:13 aleale yes + Oct 27 13:09:14 arigo yes + Oct 27 13:09:14 hpk yip + Oct 27 13:09:32 pedronis ok + Oct 27 13:09:37 mwh hpk: i was hoping to include more than what happens in irc.. + Oct 27 13:09:46 ericvrp yeys + Oct 27 13:09:46 * arigo must leave, sorry + Oct 27 13:09:48 mwh though of course, that's currently the hardest thing to find + Oct 27 13:09:52 hpk mwh: ok, also ping me sometime so we make this more visible on the web page + Oct 27 13:09:58 * arigo has quit (Remote closed the connection) + Oct 27 13:10:04 mwh but, yes, agreed for now, let's move on + Oct 27 13:10:16 cfbolz good! + Oct 27 13:10:16 cfbolz "this week on #pypy" + Oct 27 13:10:16 cfbolz -------------------------- + Oct 27 13:10:20 cfbolz sorry :-) + Oct 27 13:10:30 cfbolz new release + Oct 27 13:10:30 cfbolz -------------------------- + Oct 27 13:10:30 stakkars should I post? + Oct 27 13:10:35 cfbolz stakkars: ok + Oct 27 13:11:03 stakkars DONE: benchmarks, some stackless optimizations + Oct 27 13:11:22 stakkars plus some windows stuff + Oct 27 13:11:24 stakkars NEXT: reviews, 2 weeks Beverly Hills + Oct 27 13:11:35 stakkars BLOCK: None (except for my mother's cancer) + Oct 27 13:11:53 cfbolz sorry for that + Oct 27 13:12:05 stakkars :( thx + Oct 27 13:12:11 cfbolz ok, on to the release! + Oct 27 13:12:28 pedronis I have started updating getting started + Oct 27 13:12:45 pedronis I can write the release announcement + Oct 27 13:13:07 pedronis the question is what to highlight, and when to freeze + Oct 27 13:13:21 cfbolz and how much work should go in + Oct 27 13:13:24 * hpk still needs to catch up regarding the release planning, apparently + Oct 27 13:13:42 cfbolz hpk: no, it's new to everybody :-) + Oct 27 13:13:49 hpk ah ok. + Oct 27 13:14:07 cfbolz basically this is the first big mention since paris + Oct 27 13:14:10 mwh the highlight of this release is the working/translatable astcompiler? + Oct 27 13:14:12 aleale I think speed and compiler are the highlights + Oct 27 13:14:19 hpk ok, so the idea is to do a 0.8 release and main features are - compiler integration and more speed? + Oct 27 13:14:22 pedronis well we have add quiite a few improvement since 0.7 + Oct 27 13:14:39 stakkars include stackless? + Oct 27 13:14:41 pedronis but it also driven by EU things + Oct 27 13:14:43 cfbolz hpk: yes, and better translate_pypy, translatable thunks + Oct 27 13:14:49 hpk cfbolz: yip + Oct 27 13:14:57 mwh how well does "a flexible parser/compiler implementation" describe our situation? + Oct 27 13:15:05 mwh stakkars: that's phase 2 isn't it? :) + Oct 27 13:15:09 pedronis stakkars: that's a question, because stackless is not user visible + Oct 27 13:15:22 mwh and yes, no app level interface yet afaik + Oct 27 13:15:23 hpk i'd like to keep the release small and mean + Oct 27 13:15:27 hpk also to not incur too much work + Oct 27 13:15:30 cfbolz hpk: I agree + Oct 27 13:15:41 aleale hpk: I agree + Oct 27 13:15:42 pedronis hpk: the plan is to package what we have + Oct 27 13:15:43 stakkars it has no interface yet but by not crashing. But do we announce it as part of the release? + Oct 27 13:15:46 mwh i agree + Oct 27 13:15:58 * hpk wouldn't include stackless at this point + Oct 27 13:16:06 mwh what work needs to be done? who should do it? + Oct 27 13:16:06 pedronis we may need to disable some socket stuff + Oct 27 13:16:07 hpk but rather go for a 0.9 later in december (x-mas release) or so + Oct 27 13:16:13 pedronis which is very unstable + Oct 27 13:16:27 pedronis I mean failing tests + Oct 27 13:16:30 mwh i'm not amazingly busy, but need to be told what to do :) + Oct 27 13:16:52 pedronis mwh do you want to do more refactoring + Oct 27 13:16:54 hpk i guess i will need to be around during the release time so i'd actually first like to get an idea of the timing + Oct 27 13:16:57 mwh copy dist to release/0.8.x, disable socket on the branch, write an announce,ent? + Oct 27 13:16:59 * ericvrp would like to know when 0.8 is scheduled + Oct 27 13:17:01 mwh pedronis: yes + Oct 27 13:17:16 pedronis well, I think it should happen next week + Oct 27 13:17:22 hpk to state things upfront from my side: basically only 11th-15th if somewhat feasilbe as a release time, if i should be of much help. + Oct 27 13:17:39 mwh it would be good to get it done before then, imho + Oct 27 13:17:44 hpk pedronis: next week? uh. + Oct 27 13:17:50 pedronis hpk: yes + Oct 27 13:18:06 cfbolz how much is holger neede? + Oct 27 13:18:10 cfbolz needed + Oct 27 13:18:42 cfbolz or is everybody fine with 11-15? + Oct 27 13:18:49 stakkars maybe he can fork? + Oct 27 13:18:50 hpk why the rush? last times when i pushed for releases, we had like 3- + Oct 27 13:18:50 hpk i basically did much of the ground work the last times + Oct 27 13:19:16 * hpk thinks he _may_ be able to make it next week, is still in marocco though, but is a bit un-happy about the sudden rush + Oct 27 13:19:16 pedronis cfbolz: I need the release done + Oct 27 13:19:26 pedronis to finish the report + Oct 27 13:19:36 cfbolz pedronis: I see + Oct 27 13:19:57 pedronis and 11-15 I'm holiday myself (finally) + Oct 27 13:20:01 stakkars I'm only very little available until the 15th,at least. + Oct 27 13:20:04 cfbolz oh + Oct 27 13:20:27 cfbolz so basically next week michael, samuele and (maybe) me would be there. of the people here today + Oct 27 13:20:32 cfbolz aleale: what are your plans? + Oct 27 13:20:42 mwh how much work is a release? + Oct 27 13:20:47 aleale I am available + Oct 27 13:20:57 mwh if the answer is "not much" then ... + Oct 27 13:21:00 cfbolz mwh: depends on whether you want to look at compliancy? + Oct 27 13:21:00 pedronis hpk: it seems the part that needs you is uploading? or can that be done by someone else? + Oct 27 13:21:10 aleale mostly next week - less the week after + Oct 27 13:21:18 hpk mwh: it used to be quite a lot (some full 5 days from my side in the very last time) + Oct 27 13:21:29 hpk mwh: but i think it could be less now, i prepared some scripts and such by now + Oct 27 13:21:53 hpk pedronis: not quite, there are some details, have to think about it. but maybe you could all do it. + Oct 27 13:22:14 pedronis hpk: I also think is good think that releases don't depend on a single person + Oct 27 13:22:21 hpk pedronis: of course ! + Oct 27 13:22:24 cfbolz :-) + Oct 27 13:22:29 hpk pedronis: i am pushing for that for a long time, mind you + Oct 27 13:22:36 cfbolz good training opportunity then + Oct 27 13:22:45 stakkars ping (checking if my GPRS modem is still online,train is moving) + Oct 27 13:22:49 aleale could we do a dry run in the weekend ? + Oct 27 13:23:04 hpk pedronis: and so far, my tries to get some ahead-planning for releases have met skepticism, haven't they? + Oct 27 13:23:06 mwh as in two days time? + Oct 27 13:23:13 mwh i am away climbing + Oct 27 13:23:31 pedronis mwh: when can we freeze + Oct 27 13:23:46 pedronis it seems it depends when you are happy with refactorings you are doing? + Oct 27 13:23:49 stakkars I can help on the weekend and Monday + Oct 27 13:23:57 cfbolz so do we try to get the release out, say, friday next week? + Oct 27 13:24:00 mwh pedronis: i can easily just stop for a few days + Oct 27 13:24:18 pedronis I would freeze tomorrow then and run the tests + Oct 27 13:24:31 cfbolz ok, so very fast :-) + Oct 27 13:24:44 mwh fine with me + Oct 27 13:24:49 pedronis well running the compliancy tests take some time + Oct 27 13:25:07 pedronis and we are in a situation when we can package what we have + Oct 27 13:25:08 stakkars why disable socket,toomuch missing or too many bugs? + Oct 27 13:25:17 pedronis failing tests + Oct 27 13:25:21 pedronis some even with segfaults + Oct 27 13:25:22 cfbolz segfaults + Oct 27 13:25:31 stakkars mupf + Oct 27 13:25:41 mwh platform dependent crap too + Oct 27 13:25:41 pedronis unless someone has a lot of time to put in that + Oct 27 13:25:47 pedronis is safer to disable + Oct 27 13:25:54 cfbolz I would say we disable + Oct 27 13:25:56 mwh pedronis: +1 to disable fro 0.8 + Oct 27 13:26:00 pedronis is not really a release highlight and is far from finished + Oct 27 13:26:04 * hpk is not too happy about being mostly ignored + Oct 27 13:26:20 stakkars ? + Oct 27 13:27:17 pedronis hpk: our previous releases and always been charaterize by having to finish features at the last minute + Oct 27 13:27:23 pedronis s/and/have + Oct 27 13:27:57 * mwh points at the time + Oct 27 13:27:58 stakkars not so tjhis time if we infact throw out what isn't finished. + Oct 27 13:28:00 * ericvrp proposes to disable translator/js too + Oct 27 13:28:20 cfbolz hpk: you still there? + Oct 27 13:28:23 hpk yes + Oct 27 13:28:30 pedronis erivrp: yes, I tried to install js and lots of tests indeed fail + Oct 27 13:28:44 * hpk is thinking about if/how it all fits together. + Oct 27 13:29:07 cfbolz not at all :-( + Oct 27 13:29:14 stakkars what about llvm + Oct 27 13:29:18 hpk pedronis: the thing is, for example, that there is currently some migration regarding the codespeak backup underway + Oct 27 13:29:29 stakkars part of the release? disable the opaque stuff or finish? + Oct 27 13:29:48 cfbolz could we decide how to decide? some more decision at 2 on #pypy? + Oct 27 13:29:49 ericvrp stakkars: pypy-llvm works + Oct 27 13:29:50 hpk pedronis: i suggest to _try_ going for a friday release next week + Oct 27 13:30:09 pedronis hpk: that's ok + Oct 27 13:30:14 stakkars ericvrp: already? whow! + Oct 27 13:30:15 hpk pedronis: but merlinux also has another deadline on that very day :( (and the consortium meeting is there as well) + Oct 27 13:30:16 cfbolz ok, everybody fine with that? + Oct 27 13:30:27 aleale ok + Oct 27 13:30:32 stakkars ok + Oct 27 13:30:34 ericvrp ok + Oct 27 13:30:39 mwh ok + Oct 27 13:30:46 pedronis hpk: we should try to have a finalized tag before then + Oct 27 13:30:57 pedronis such that is a matter of pushing it out + Oct 27 13:31:04 hpk pedronis: of course. a ctually i sugest a planning meeting on monday or so + Oct 27 13:31:19 hpk pedronis: trust me, it is or at least used to be quite a lot of work to get a release out + Oct 27 13:31:26 pedronis hpk: makes sense + Oct 27 13:31:38 pedronis I still plan to make a branch tomorrow + Oct 27 13:31:42 cfbolz ok, let's close the meeting now + Oct 27 13:31:45 * hpk is off to another meeting + Oct 27 13:31:46 pedronis so that on monday we can see + Oct 27 13:31:50 cfbolz see you all later on #pypy! + Oct 27 13:31:52 cfbolz bye! + Oct 27 13:31:57 aleale bye + Oct 27 13:32:04 pedronis whether we have serious compliancy regressions + Oct 27 13:32:11 * aleale (n=andersle at clogs.dfki.uni-sb.de) has left #pypy-sync + Oct 27 13:32:16 * pedronis hopes not + Oct 27 13:32:20 ericvrp bye + Oct 27 13:32:25 mwh bye + Oct 27 13:32:28 * mwh (n=user at 82-33-200-181.cable.ubr01.azte.blueyonder.co.uk) has left #pypy-sync ("ERC Version 5.0 (CVS) $Revision: 1.771 $ (IRC client for Emacs)") + Oct 27 13:32:34 * ericvrp (n=chatzill at ericvrp.demon.nl) has left #pypy-sync + Oct 27 13:37:00 * bertf has quit () + Oct 27 13:56:09 * stakkars has quit (Read error: 110 (Connection timed out)) + **** ENDING LOGGING AT Thu Oct 27 14:03:31 2005 + From cfbolz at codespeak.net Thu Oct 27 22:35:16 2005 From: cfbolz at codespeak.net (cfbolz at codespeak.net) Date: Thu, 27 Oct 2005 22:35:16 +0200 (CEST) Subject: [pypy-svn] r19098 - pypy/extradoc/minute Message-ID: <20051027203516.075CD27B90@code1.codespeak.net> Author: cfbolz Date: Thu Oct 27 22:35:15 2005 New Revision: 19098 Added: pypy/extradoc/minute/pypy-sync-10-27-2005.txt - copied, changed from r19097, pypy/extradoc/minute/pypy-sync-10-27.txt Removed: pypy/extradoc/minute/pypy-sync-10-27.txt Log: hum From mwh at codespeak.net Fri Oct 28 10:44:39 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 10:44:39 +0200 (CEST) Subject: [pypy-svn] r19099 - pypy/dist/pypy/tool Message-ID: <20051028084439.617D727B64@code1.codespeak.net> Author: mwh Date: Fri Oct 28 10:44:37 2005 New Revision: 19099 Modified: pypy/dist/pypy/tool/importfun.py Log: check in of html generation code, and probably assorted other stuff too. Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Fri Oct 28 10:44:37 2005 @@ -3,8 +3,8 @@ import dis import imp import os -from sys import path, prefix import __builtin__ +import time """ so design goal: @@ -138,7 +138,7 @@ self.importers = [] def import_(self, modname): if modname not in self._imports: - if modname not in self.system.modules: + if recursive and modname not in self.system.modules: self.system.pendingmodules[modname] = None self._imports[modname] = {} return self._imports[modname] @@ -275,7 +275,7 @@ else: storename = codeob.co_names[oparg] - + if mod: scope.modvars[storename] = submod else: @@ -333,61 +333,47 @@ process(r, c, Scope(scope)) def process_module(dottedname, system): - path = find_from_dotted_name(dottedname) + if dottedname.endswith('.py'): + path = dottedname + dottedname = path.lstrip('./').rstrip()[:-3].replace('/', '.') + else: + path = find_from_dotted_name(dottedname) + ispackage = False if os.path.isdir(path): ispackage = True path += '/__init__.py' - code = compile(open(path, "U").read(), '', 'exec') r = Module(dottedname, system) r.ispackage = ispackage + if dottedname in system.modules: + return system.modules[dottedname] + try: + code = compile(open(path, "U").read(), path, 'exec') process(r, code, r.toplevelscope, True) - except ImportError, e: + except (ImportError, AssertionError, SyntaxError), e: print "failed!", e else: - assert dottedname not in system.pendingmodules + if dottedname in system.pendingmodules: + print + del system.pendingmodules[dottedname] system.modules[dottedname] = r return r -a = 1 - def find_from_dotted_name(modname): path = None for part in modname.split('.'): - path = [imp.find_module(part, path)[1]] + try: + path = [imp.find_module(part, path)[1]] + except ImportError: + print modname + raise return path[0] -def main(path): - system = System() - system.pendingmodules[path] = None - while system.pendingmodules: - path, d = system.pendingmodules.popitem() - print '\r', len(system.pendingmodules), path, ' ', - sys.stdout.flush() - if not path.startswith('pypy.') or path == 'pypy._cache': - continue - process_module(path, system) - - # strip out non-pypy imports -## for name, mod in system.modules.iteritems(): -## for n in mod._imports.copy(): -## if not n.startswith('pypy.') or n == 'pypy._cache': -## del mod._imports[n] - - # record importer information -# for name, mod in system.modules.iteritems(): -# for n in mod._imports: -# system.modules[n].importers.append(name) - - unuseds = {} - - print - print '------' - +def report_unused_symbols(system): for name, mod in sorted(system.modules.iteritems()): printed = False if not 'pypy.' in name or '_cache' in name: @@ -422,7 +408,205 @@ printed = True for k, v in u.iteritems(): print ' ', k, v - + +def find_cycles(system): + from pypy.tool.algo import graphlib + vertices = dict.fromkeys(system.modules) + edges = {} + for m in system.modules: + edges[m] = [] + for n in system.modules[m]._imports: + edges[m].append(graphlib.Edge(m, n)) + cycles = [] + for component in graphlib.strong_components(vertices, edges): + random_vertex = component.iterkeys().next() + cycles.extend(graphlib.all_cycles(random_vertex, component, edges)) + + ncycles = [] + for cycle in cycles: + packs = {} + for edge in cycle: + package = edge.source.rsplit('.', 1)[0] + packs[package] = True + if len(packs) > 1: + ncycles.append(cycle) + cycles = ncycles + + for cycle in cycles: + l = len(cycle[0].source) + print cycle[0].source, '->', cycle[0].target + for edge in cycle[1:]: + print ' '*l, '->', edge.target + print len(cycles), 'inter-package cycles' + +def summary(system): + mcount = float(len(system.modules)) + importcount = 0 + importstars = 0 + importstarusage = 0 + defcount = 0 + importedcount = 0 + for m in system.modules: + m = system.modules[m] + defcount += len(m.definitions) + importedcount += len(m.importers) + importcount += len(m._imports) + for n in m._imports: + if '*' in m._imports[n]: + importstars += 1 + importstarusage += len([o for (o, v) in m._imports[n].iteritems() if v == True]) + print + print 'the average module' + print 'was imported %.2f times'%(importedcount/mcount) + print 'imported %.2f other modules'%(importcount/mcount) + print 'defined %.2f names'%(defcount/mcount) + print + print 'there were %d import *s'%(importstars) + print 'the average one produced %.2f names that were actually used'\ + %((1.0*importstarusage)/importstars) + +def not_imported(system): + for m, M in sorted(system.modules.iteritems()): + if not M.importers and 'test' not in m and '__init__' not in m: + print m + +def import_stars(system): + for m in sorted(system.modules): + m = system.modules[m] + for n in sorted(m._imports): + if '*' in m._imports[n]: + print m.name, 'imports * from', n + used = [o for (o, v) in m._imports[n].iteritems() if v == True and o != '*'] + print len(used), 'out of', len(m._imports[n]) - 1, 'names are used' + print ' ', ', '.join(sorted(used)) + +def find_varargs_users(system): + for m in sorted(system.modules): + m = system.modules[m] + if 'pypy.interpreter.pycode' in m._imports: + if m._imports['pypy.interpreter.pycode'].get('CO_VARARGS') == True: + print m.name + + +def html_for_module(module): + from py.xml import html + out = open('importfunhtml/%s.html'%module.name, 'w') + head = [html.title(module.name)] + body = [html.h1(module.name)] + body.append(html.p('This module defines these names:')) + listbody = [] + for d in module.definitions: + if not d.startswith('_'): + listbody.append(html.li( + html.a(d, href=module.name+'-'+d+'.html'))) + body.append(html.ul(listbody)) + body.append(html.p('This module imports the following:')) + listbody1 = [] + for n in sorted(module._imports): + if n in module.system.modules: + listbody2 = [html.a(n, href=n+'.html')] + else: + listbody2 = [n] + listbody3 = [] + for o in sorted(module._imports[n]): + if module._imports[n][o] == True: + if n in module.system.modules: + listbody3.append( + html.li(html.a(o, href=n+'-'+o+'.html'))) + else: + listbody3.append(html.li(o)) + if listbody3: + listbody2.append(html.ul(listbody3)) + listbody1.append(html.li(listbody2)) + body.append(html.ul(listbody1)) + body.append(html.p('This module is imported by the following:')) + listbody1 = [] + for n in module.importers: + licontents = [html.a(n, href=n+'.html')] + contents = [] + for o in sorted(module.system.modules[n]._imports[module.name]): + contents.append(html.li(html.a(o, href=module.name+'-'+o+'.html'))) + if contents: + licontents.append(html.ul(contents)) + listbody1.append(html.li(licontents)) + body.append(html.ul(listbody1)) + + out.write(html.html(head, body).unicode()) + + for d in module.definitions: + out = open('importfunhtml/%s-%s.html'%(module.name, d), 'w') + head = [html.title(module.name + '.' + d)] + body = [html.h1([html.a(module.name, href=module.name+'.html'), '.' + d])] + + contents = [] + + for n in module.importers: + if module.system.modules[n]._imports[module.name].get(d) == True: + contents.append(html.li(html.a(n, href=n+'.html'))) + + if contents: + body.append(html.p('This name is used in')) + body.append(html.ul(contents)) + else: + body.append(html.p('This name is not used outside the module.')) + + out.write(html.html(head, body).unicode()) + +def make_html_report(system): + if os.path.isdir('importfunhtml'): + os.system('rm -rf importfunhtml') + os.mkdir('importfunhtml') + for m in system.modules.itervalues(): + html_for_module(m) + +def main(*paths): + system = System() + + for path in paths: + system.pendingmodules[path] = None + + T = time.time() + + while system.pendingmodules: + path, d = system.pendingmodules.popitem() + print '\r', len(system.pendingmodules), path, ' ', + sys.stdout.flush() + if '._cache' in path or '/_cache' in path: + continue + if '/' not in path and not path.startswith('pypy.'): + continue + process_module(path, system) + + print + print 'analysed', len(system.modules), 'modules in %.2f seconds'%(time.time() - T) + print '------' + + # record importer information + for name, mod in system.modules.iteritems(): + for n in mod._imports: + if n in system.modules: + system.modules[n].importers.append(name) + + make_html_report(system) + + if interactive: + import pdb + pdb.set_trace() + +recursive = False +interactive = False if __name__=='__main__': - main(*sys.argv[1:]) + if '-r' in sys.argv: + recursive = True + sys.argv.remove('-r') + if '-i' in sys.argv: + interactive = True + sys.argv.remove('-i') + if len(sys.argv) > 1: + main(*sys.argv[1:]) + else: + paths = [] + for line in os.popen("find pypy -name '*.py'"): + paths.append(line[:-1]) + main(*paths) From mwh at codespeak.net Fri Oct 28 11:26:34 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 11:26:34 +0200 (CEST) Subject: [pypy-svn] r19100 - pypy/dist/pypy/tool Message-ID: <20051028092634.5A1EF27BA0@code1.codespeak.net> Author: mwh Date: Fri Oct 28 11:26:32 2005 New Revision: 19100 Modified: pypy/dist/pypy/tool/importfun.py Log: generate html in nested directories rather than dumping 10k files in a single directory... Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Fri Oct 28 11:26:32 2005 @@ -488,9 +488,40 @@ print m.name +def file_for_module(module): + fname = os.path.join('importfunhtml', *module.name.split('.')) + '.html' + dname = os.path.dirname(fname) + if not os.path.isdir(dname): + os.makedirs(dname) + return open(fname, 'w') + +def link_for_module(fromlink, module): + link = '/'.join(module.name.split('.')) + '.html' + prefix = '/'.join(['..']*fromlink.count('/')) + if prefix: + return prefix + '/' + link + else: + return link + +def file_for_name(module, name): + fname = os.path.join('importfunhtml', *(module.name.split('.') + [name])) + '.html' + dname = os.path.dirname(fname) + if not os.path.isdir(dname): + os.makedirs(dname) + return open(fname, 'w') + +def link_for_name(fromlink, module, name): + link = '/'.join(module.name.split('.') + [name]) + '.html' + prefix = '/'.join(['..']*fromlink.count('/')) + if prefix: + return prefix + '/' + link + else: + return link + def html_for_module(module): from py.xml import html - out = open('importfunhtml/%s.html'%module.name, 'w') + out = file_for_module(module) + ourlink = link_for_module('', module) head = [html.title(module.name)] body = [html.h1(module.name)] body.append(html.p('This module defines these names:')) @@ -498,13 +529,14 @@ for d in module.definitions: if not d.startswith('_'): listbody.append(html.li( - html.a(d, href=module.name+'-'+d+'.html'))) + html.a(d, href=link_for_name(ourlink, module, d)))) body.append(html.ul(listbody)) body.append(html.p('This module imports the following:')) listbody1 = [] for n in sorted(module._imports): if n in module.system.modules: - listbody2 = [html.a(n, href=n+'.html')] + listbody2 = [html.a( + n, href=link_for_module(ourlink, module.system.modules[n]))] else: listbody2 = [n] listbody3 = [] @@ -512,7 +544,8 @@ if module._imports[n][o] == True: if n in module.system.modules: listbody3.append( - html.li(html.a(o, href=n+'-'+o+'.html'))) + html.li(html.a( + o, href=link_for_name(ourlink, module.system.modules[n], o)))) else: listbody3.append(html.li(o)) if listbody3: @@ -522,10 +555,10 @@ body.append(html.p('This module is imported by the following:')) listbody1 = [] for n in module.importers: - licontents = [html.a(n, href=n+'.html')] + licontents = [html.a(n, href=link_for_module(ourlink, module.system.modules[n]))] contents = [] for o in sorted(module.system.modules[n]._imports[module.name]): - contents.append(html.li(html.a(o, href=module.name+'-'+o+'.html'))) + contents.append(html.li(html.a(o, href=link_for_name(ourlink, module, o)))) if contents: licontents.append(html.ul(contents)) listbody1.append(html.li(licontents)) @@ -534,15 +567,17 @@ out.write(html.html(head, body).unicode()) for d in module.definitions: - out = open('importfunhtml/%s-%s.html'%(module.name, d), 'w') + out = file_for_name(module, d) + ourlink = link_for_name('', module, d) head = [html.title(module.name + '.' + d)] - body = [html.h1([html.a(module.name, href=module.name+'.html'), '.' + d])] + body = [html.h1([html.a(module.name, href=link_for_module(ourlink, module)), '.' + d])] contents = [] for n in module.importers: - if module.system.modules[n]._imports[module.name].get(d) == True: - contents.append(html.li(html.a(n, href=n+'.html'))) + N = module.system.modules[n] + if N._imports[module.name].get(d) == True: + contents.append(html.li(html.a(n, href=link_for_module(ourlink, N)))) if contents: body.append(html.p('This name is used in')) @@ -569,8 +604,9 @@ while system.pendingmodules: path, d = system.pendingmodules.popitem() - print '\r', len(system.pendingmodules), path, ' ', - sys.stdout.flush() + if sys.stdout.isatty(): + print '\r\033[K', len(system.pendingmodules), path, + sys.stdout.flush() if '._cache' in path or '/_cache' in path: continue if '/' not in path and not path.startswith('pypy.'): From hpk at codespeak.net Fri Oct 28 11:55:05 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 28 Oct 2005 11:55:05 +0200 (CEST) Subject: [pypy-svn] r19102 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028095505.8EF4527BA8@code1.codespeak.net> Author: hpk Date: Fri Oct 28 11:55:03 2005 New Revision: 19102 Modified: pypy/extradoc/talk/pycon2006/draft-soft.txt Log: some work on adapting towards a "social" pycon proposal, didn'T change much actual content which seem to fit quite well, still. Modified: pypy/extradoc/talk/pycon2006/draft-soft.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/draft-soft.txt (original) +++ pypy/extradoc/talk/pycon2006/draft-soft.txt Fri Oct 28 11:55:03 2005 @@ -1,16 +1,14 @@ -Reference/Call For Papers: http://www.ccc.de/congress/2005/cfp.html -DEADLINE: 31st September 2005 (friday) +DEADLINE: 31st October 2005 -Title: agile open-source methods <-> business/EU-funding +Title: agile open-source methods, businesses and EU-funding Subtitle: Sprint driven development in Open Source projects - agile methods in open-source related companies -Section: Hacker(ethik), (or Culture? or Community?) - Talkers: Beatrice D?ring, Holger Krekel -Abstract (max 250 letters): +Short description +-------------------- There is a growing number of open-source developers organized and connected to company and money related work. @@ -18,7 +16,8 @@ project which has a 7 company/university consortium and a 1.3 Million Euro research grant from the European Union. -Description (250-500 words): +Presentation outline +-------------------- We'd like to present and discuss models and experiences for connecting open-source/hacking culture driven development @@ -40,22 +39,14 @@ the OSS perspective, EU perspective and the Chaos Pilot/process management perspective - managing diversities. -Statement: We intend to submit a paper (PDF) for the 22C3 proceedings. -Statement: We intend to submit a slides PDF as well. - -Duration of your talk: 45 minutes + questions -Language of your talk: english +Duration of your talk: 30 minutes + questions Links to background information on the talk: http://codespeak.net/pypy/dist/pypy/doc/dev_method.html http://codespeak.net/pypy/dist/pypy -Target Group: Advanced Users, Pros - -Resources you need for your talk: digital projector, internet - -Related talks at 22C3 you know of: PyPy - the new Python implementation on the block +Target Group: Advanced Users, Pros A lecture logo, square format, min. 128x128 pixels (optional): http://codespeak.net/pypy/img/py-web1.png From hpk at codespeak.net Fri Oct 28 11:55:35 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 28 Oct 2005 11:55:35 +0200 (CEST) Subject: [pypy-svn] r19103 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028095535.1DD9D27BAB@code1.codespeak.net> Author: hpk Date: Fri Oct 28 11:55:32 2005 New Revision: 19103 Added: pypy/extradoc/talk/pycon2006/pylib.txt (contents, props changed) Log: another talk proposal about the py lib (not 100% sure yet if i submit that) Added: pypy/extradoc/talk/pycon2006/pylib.txt ============================================================================== --- (empty file) +++ pypy/extradoc/talk/pycon2006/pylib.txt Fri Oct 28 11:55:32 2005 @@ -0,0 +1,65 @@ +Author Names +------------ + +(from) Holger Krekel + +Contact Information +------------------- + +holger krekel + +Requested Timeslot +------------------ + +30 minutes (or 45 minutes. both possible). + + +Summary of proposed presentation +-------------------------------- + +Title: py library and beyond + +Already known for its widely used "py.test" testing tool, the +"py lib" has more to offer. We are going to explore the +experimental package "name export mechanism" involving lazy +imports, a lightweight tag/keyword-based logging scheme, +subversion and local Path objects and compatibility modules that +make recent Python library modules uniformly available from older +Python versions. We also will glance into the current state of +"py.execnet" which explores new interprocess-communication +facilities. All of these features are already used by a growing +number of projects. We will give an overview of what comes next. + +Presentation Outline +-------------------- + +The py lib is a development support library +and evolves from a strictly test-driven process. +Apart from its intense usage in the PyPy project +a number of other projects have adapted its methods. + +The current key parts of the py lib we are to present: + +- py.log: keyword & subscription based lazy logging +- py.compat: use newer standard library modules from older + python versions +- py.initpkg: export name/lazy import mechanism ("import py" + is all you ever need to do). +- py.path.*: path objects unifying access to svn- and + local filesystems. +- py.execnet: distributing programs across ssh- and process + networks. + +We look at the next challenges for py lib development: + +- extending py.execnet to use it for peer-to-peer situations +- extending/refactoring py.path to support in-memory + and other filesystems +- integrating twisted testing functionality into py.test +- release plan + +Intended audience +----------------- + +All python developers (who are interested in lightweight libraries and +lean pythonnic APIs in order to support agile development). From mwh at codespeak.net Fri Oct 28 11:56:07 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 11:56:07 +0200 (CEST) Subject: [pypy-svn] r19104 - pypy/dist/pypy/tool Message-ID: <20051028095607.20AE027BA8@code1.codespeak.net> Author: mwh Date: Fri Oct 28 11:56:06 2005 New Revision: 19104 Modified: pypy/dist/pypy/tool/importfun.py Log: Don't generate an html file for a name that's only used in the module that defines it (cuts the amount of generated html by like two thirds!). Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Fri Oct 28 11:56:06 2005 @@ -150,7 +150,7 @@ op = ord(codestring[i]) i += 1 oparg = None - assert op != opcode.EXTENDED_ARG + assert op != opcode.EXTENDED_ARG, 'EXTENDED_ARG' if op >= opcode.HAVE_ARGUMENT: oparg = ord(codestring[i]) + ord(codestring[i+1])*256 i += 2 @@ -187,7 +187,7 @@ if op == IMPORT_NAME: preop, preoparg = opcodes[i-1] - assert preop == LOAD_CONST + assert preop == LOAD_CONST, 'LOAD_CONST' fromlist = codeob.co_consts[preoparg] @@ -203,7 +203,10 @@ #assert not '.' in modname - assert postop in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL] + # this assert actually triggers quite frequently, for things like + # import py.lib as lib + # (which is strange code, in my book...) + assert postop in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL], 'postop' if postop == STORE_FAST: storename = codeob.co_varnames[postoparg] elif postop == STORE_DEREF: @@ -217,7 +220,7 @@ scope.modvars[storename] = modname.split('.')[0] i += 1 elif fromlist == ('*',): - assert toplevel + assert toplevel, 'toplevel' if modname.startswith('pypy.'): if modname not in r.system.modules: if modname in r.system.pendingmodules: @@ -242,8 +245,8 @@ i += 1 for f in fromlist: op, oparg = opcodes[i] - assert op == IMPORT_FROM - assert codeob.co_names[oparg] == f + assert op == IMPORT_FROM, 'IMPORT_FROM' + assert codeob.co_names[oparg] == f, 'f' i += 1 if path == -1: @@ -264,7 +267,7 @@ op, oparg = opcodes[i] - assert op in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL] + assert op in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL], 'opstore' if op == STORE_FAST: storename = codeob.co_varnames[oparg] elif op == STORE_DEREF: @@ -282,7 +285,7 @@ scope.varsources[storename] = modname, f i += 1 op, oparg = opcodes[i] - assert op == POP_TOP + assert op == POP_TOP, 'POP_TOP' elif op == STORE_NAME and toplevel or op == STORE_GLOBAL: r.definitions.append(codeob.co_names[oparg]) elif op == LOAD_ATTR: @@ -299,7 +302,7 @@ name = codeob.co_names[oparg] m, a = scope.var_source(name) if m: - assert a in r.import_(m) + assert a in r.import_(m), 'a' r.import_(m)[a] = True ## else: ## if name not in r.definitions \ @@ -312,7 +315,7 @@ name = codeob.co_varnames[oparg] m, a = scope.var_source(name) if m: - assert a in r.import_(m) + assert a in r.import_(m), 'a2' r.import_(m)[a] = True elif op in [LOAD_DEREF]: if oparg < len(codeob.co_cellvars): @@ -321,11 +324,11 @@ name = codeob.co_freevars[oparg - len(codeob.co_cellvars)] m, a = scope.var_source(name) if m: - assert a in r.import_(m) + assert a in r.import_(m), 'a3' r.import_(m)[a] = True elif op in [MAKE_FUNCTION, MAKE_CLOSURE]: preop, preoparg = opcodes[i-1] - assert preop == LOAD_CONST + assert preop == LOAD_CONST, 'preop' codeobjs.append(codeob.co_consts[preoparg]) i += 1 @@ -526,14 +529,28 @@ body = [html.h1(module.name)] body.append(html.p('This module defines these names:')) listbody = [] + defuses = {} for d in module.definitions: + uses = [] + for n in sorted(module.importers): + N = module.system.modules[n] + if N._imports[module.name].get(d) == True: + uses.append(n) + if not d.startswith('_'): - listbody.append(html.li( - html.a(d, href=link_for_name(ourlink, module, d)))) + if uses: + listbody.append(html.li( + html.a(d, href=link_for_name(ourlink, module, d)))) + defuses[d] = uses + else: + listbody.append(html.li(d)) + body.append(html.ul(listbody)) body.append(html.p('This module imports the following:')) listbody1 = [] for n in sorted(module._imports): + if n in ('autopath', '__future__'): + continue if n in module.system.modules: listbody2 = [html.a( n, href=link_for_module(ourlink, module.system.modules[n]))] @@ -566,25 +583,21 @@ out.write(html.html(head, body).unicode()) - for d in module.definitions: + for d in defuses: out = file_for_name(module, d) ourlink = link_for_name('', module, d) head = [html.title(module.name + '.' + d)] body = [html.h1([html.a(module.name, href=link_for_module(ourlink, module)), '.' + d])] - + contents = [] - for n in module.importers: + for n in defuses[d]: N = module.system.modules[n] - if N._imports[module.name].get(d) == True: - contents.append(html.li(html.a(n, href=link_for_module(ourlink, N)))) + contents.append(html.li(html.a(n, href=link_for_module(ourlink, N)))) + + body.append(html.p('This name is used in')) + body.append(html.ul(contents)) - if contents: - body.append(html.p('This name is used in')) - body.append(html.ul(contents)) - else: - body.append(html.p('This name is not used outside the module.')) - out.write(html.html(head, body).unicode()) def make_html_report(system): @@ -605,7 +618,7 @@ while system.pendingmodules: path, d = system.pendingmodules.popitem() if sys.stdout.isatty(): - print '\r\033[K', len(system.pendingmodules), path, + print '\r\033[K', len(system.modules), '/', len(system.pendingmodules), path, sys.stdout.flush() if '._cache' in path or '/_cache' in path: continue From hpk at codespeak.net Fri Oct 28 12:00:29 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 28 Oct 2005 12:00:29 +0200 (CEST) Subject: [pypy-svn] r19105 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028100029.795D527BAE@code1.codespeak.net> Author: hpk Date: Fri Oct 28 12:00:27 2005 New Revision: 19105 Modified: pypy/extradoc/talk/pycon2006/pylib.txt Log: i guess this should be a tutorial (after reading the guidelines for pycon submissions) Modified: pypy/extradoc/talk/pycon2006/pylib.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pylib.txt (original) +++ pypy/extradoc/talk/pycon2006/pylib.txt Fri Oct 28 12:00:27 2005 @@ -11,13 +11,12 @@ Requested Timeslot ------------------ -30 minutes (or 45 minutes. both possible). - +45 minutes tutorial. Summary of proposed presentation -------------------------------- -Title: py library and beyond +Title: using the py library (apart from py.test) Already known for its widely used "py.test" testing tool, the "py lib" has more to offer. We are going to explore the @@ -28,7 +27,8 @@ Python versions. We also will glance into the current state of "py.execnet" which explores new interprocess-communication facilities. All of these features are already used by a growing -number of projects. We will give an overview of what comes next. +number of projects. We will give interactive examples and +conclude with an overview of what comes next. Presentation Outline -------------------- @@ -37,8 +37,9 @@ and evolves from a strictly test-driven process. Apart from its intense usage in the PyPy project a number of other projects have adapted its methods. - -The current key parts of the py lib we are to present: +We plan to give usage examples for various parts +of the py library. The current key parts of the py lib +we are to present: - py.log: keyword & subscription based lazy logging - py.compat: use newer standard library modules from older @@ -47,10 +48,10 @@ is all you ever need to do). - py.path.*: path objects unifying access to svn- and local filesystems. -- py.execnet: distributing programs across ssh- and process - networks. +- py.execnet: ad-hoc distributing programs across ssh- and process + barriers. -We look at the next challenges for py lib development: +We'll conclude with the next challenges for py lib development: - extending py.execnet to use it for peer-to-peer situations - extending/refactoring py.path to support in-memory From mwh at codespeak.net Fri Oct 28 12:33:03 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 12:33:03 +0200 (CEST) Subject: [pypy-svn] r19106 - pypy/dist/pypy/tool Message-ID: <20051028103303.A2B1C27BA2@code1.codespeak.net> Author: mwh Date: Fri Oct 28 12:33:02 2005 New Revision: 19106 Modified: pypy/dist/pypy/tool/importfun.py Log: some fairly straightforward refactoring. Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Fri Oct 28 12:33:02 2005 @@ -156,24 +156,32 @@ i += 2 yield op, oparg -STORE_DEREF = opcode.opmap["STORE_DEREF"] -STORE_FAST = opcode.opmap["STORE_FAST"] -STORE_GLOBAL = opcode.opmap["STORE_GLOBAL"] -STORE_NAME = opcode.opmap["STORE_NAME"] -IMPORT_NAME = opcode.opmap["IMPORT_NAME"] -IMPORT_FROM = opcode.opmap["IMPORT_FROM"] -LOAD_CONST = opcode.opmap["LOAD_CONST"] -LOAD_ATTR = opcode.opmap["LOAD_ATTR"] - -LOAD_DEREF = opcode.opmap["LOAD_DEREF"] -LOAD_FAST = opcode.opmap["LOAD_FAST"] -LOAD_NAME = opcode.opmap["LOAD_NAME"] -LOAD_GLOBAL = opcode.opmap["LOAD_GLOBAL"] -MAKE_CLOSURE = opcode.opmap["MAKE_CLOSURE"] -MAKE_FUNCTION = opcode.opmap["MAKE_FUNCTION"] +class _Op(object): + def __getattr__(self, name): + if name in opcode.opmap: + return opcode.opmap[name] + else: + raise AttributeError, name + +_op_ = _Op() + -POP_TOP = opcode.opmap['POP_TOP'] +loadops = [_op_.LOAD_NAME, _op_.LOAD_GLOBAL, _op_.LOAD_FAST, _op_.LOAD_DEREF] +storeops = [_op_.STORE_NAME, _op_.STORE_FAST, _op_.STORE_DEREF, _op_.STORE_GLOBAL] + +def name_for_op(code, op, oparg): + if op in [_op_.LOAD_GLOBAL, _op_.STORE_GLOBAL, _op_.LOAD_NAME, _op_.STORE_NAME]: + return code.co_names[oparg] + elif op in [_op_.LOAD_FAST, _op_.STORE_FAST]: + return code.co_varnames[oparg] + elif op in [_op_.LOAD_DEREF, _op_.STORE_DEREF]: + if oparg < len(code.co_cellvars): + return code.co_cellvars[oparg] + else: + return code.co_freevars[oparg - len(code.co_cellvars)] + else: + assert 0, "%s is not an opcode with a name!"%(opcode.opname[op],) def process(r, codeob, scope, toplevel=False): opcodes = list(iteropcodes(codeob.co_code)) @@ -185,9 +193,9 @@ while i < len(opcodes): op, oparg = opcodes[i] - if op == IMPORT_NAME: + if op == _op_.IMPORT_NAME: preop, preoparg = opcodes[i-1] - assert preop == LOAD_CONST, 'LOAD_CONST' + assert preop == _op_.LOAD_CONST, 'LOAD_CONST' fromlist = codeob.co_consts[preoparg] @@ -206,17 +214,8 @@ # this assert actually triggers quite frequently, for things like # import py.lib as lib # (which is strange code, in my book...) - assert postop in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL], 'postop' - if postop == STORE_FAST: - storename = codeob.co_varnames[postoparg] - elif postop == STORE_DEREF: - if postoparg < len(codeob.co_cellvars): - storename = codeob.co_cellvars[postoparg] - else: - storename = codeob.co_freevars[postoparg - len(codeob.co_cellvars)] - else: - storename = codeob.co_names[postoparg] - + assert postop in storeops, 'postop' + storename = name_for_op(codeob, postop, postoparg) scope.modvars[storename] = modname.split('.')[0] i += 1 elif fromlist == ('*',): @@ -245,7 +244,7 @@ i += 1 for f in fromlist: op, oparg = opcodes[i] - assert op == IMPORT_FROM, 'IMPORT_FROM' + assert op == _op_.IMPORT_FROM, 'IMPORT_FROM' assert codeob.co_names[oparg] == f, 'f' i += 1 @@ -267,17 +266,8 @@ op, oparg = opcodes[i] - assert op in [STORE_NAME, STORE_FAST, STORE_DEREF, STORE_GLOBAL], 'opstore' - if op == STORE_FAST: - storename = codeob.co_varnames[oparg] - elif op == STORE_DEREF: - if oparg < len(codeob.co_cellvars): - storename = codeob.co_cellvars[oparg] - else: - storename = codeob.co_freevars[oparg - len(codeob.co_cellvars)] - else: - storename = codeob.co_names[oparg] - + assert op in storeops, 'opstore' + storename = name_for_op(codeob, op, oparg) if mod: scope.modvars[storename] = submod @@ -285,21 +275,18 @@ scope.varsources[storename] = modname, f i += 1 op, oparg = opcodes[i] - assert op == POP_TOP, 'POP_TOP' - elif op == STORE_NAME and toplevel or op == STORE_GLOBAL: + assert op == _op_.POP_TOP, 'POP_TOP' + elif op == _op_.STORE_NAME and toplevel or op == _op_.STORE_GLOBAL: r.definitions.append(codeob.co_names[oparg]) - elif op == LOAD_ATTR: + elif op == _op_.LOAD_ATTR: preop, preoparg = opcodes[i-1] - if preop in [LOAD_NAME, LOAD_GLOBAL]: - m = scope.mod_for_name(codeob.co_names[preoparg]) - if m: - r.import_(m)[codeob.co_names[oparg]] = True - elif preop in [LOAD_FAST]: - m = scope.mod_for_name(codeob.co_varnames[preoparg]) + if preop in loadops: + name = name_for_op(codeob, preop, preoparg) + m = scope.mod_for_name(name) if m: r.import_(m)[codeob.co_names[oparg]] = True - elif op in [LOAD_NAME, LOAD_GLOBAL]: - name = codeob.co_names[oparg] + elif op in loadops: + name = name_for_op(codeob, op, oparg) m, a = scope.var_source(name) if m: assert a in r.import_(m), 'a' @@ -311,24 +298,9 @@ ## and name not in __builtin__.__dict__ \ ## and (op == LOAD_GLOBAL or toplevel): ## print 'where did', name, 'come from?' - elif op in [LOAD_FAST]: - name = codeob.co_varnames[oparg] - m, a = scope.var_source(name) - if m: - assert a in r.import_(m), 'a2' - r.import_(m)[a] = True - elif op in [LOAD_DEREF]: - if oparg < len(codeob.co_cellvars): - name = codeob.co_cellvars[oparg] - else: - name = codeob.co_freevars[oparg - len(codeob.co_cellvars)] - m, a = scope.var_source(name) - if m: - assert a in r.import_(m), 'a3' - r.import_(m)[a] = True - elif op in [MAKE_FUNCTION, MAKE_CLOSURE]: + elif op in [_op_.MAKE_FUNCTION, _op_.MAKE_CLOSURE]: preop, preoparg = opcodes[i-1] - assert preop == LOAD_CONST, 'preop' + assert preop == _op_.LOAD_CONST, 'preop' codeobjs.append(codeob.co_consts[preoparg]) i += 1 @@ -357,6 +329,7 @@ process(r, code, r.toplevelscope, True) except (ImportError, AssertionError, SyntaxError), e: print "failed!", e + #raise else: if dottedname in system.pendingmodules: print From arigo at codespeak.net Fri Oct 28 12:47:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Oct 2005 12:47:29 +0200 (CEST) Subject: [pypy-svn] r19108 - pypy/dist/pypy/doc Message-ID: <20051028104729.5D00727BA2@code1.codespeak.net> Author: arigo Date: Fri Oct 28 12:47:27 2005 New Revision: 19108 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Arf! The formal proofs get more and more technical. I hope that the next one will not be hopelessly lost to anyone without a math degree. Funny that we can more or less be intuitively convinced that the annotator "works". Maybe I'm overdoing this and should use more "we can easily see that" in the proofs... Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 28 12:47:27 2005 @@ -1260,8 +1260,13 @@ As the annotation process is a fix-point search, we should prove for completeness that it is, in some sense yet to be defined, well-behaved. -The following proofs are all rather straightforward given the approach -we have taken. +Given the approach we have taken, none of the following proofs is +"deep": the intended goal of the whole approach is to allow the +development of an intuitive understanding of why annotation works. +However, despide their straightforwardness the following proofs are +quite technical; they are oriented towards the more +mathematically-minded reader. + Generalization ************** @@ -1313,7 +1318,7 @@ variable of the block itself. So assume for now that the input variables of this operation can only get generalized; we claim that in this case the same holds for its result variable. If - this holds, then we conclude by reccurence on the number of + this holds, then we conclude by induction on the number of operations in the block: indeed, starting from point 1 above for the input variables of the block, it shows that each result variable -- so also all input arguments of the next operation -- @@ -1508,8 +1513,10 @@ complete. The informal argument of the Termination_ paragraph shows that this sequence is necessarily of finite length. In the Generalization_ paragraph we have also seen that each state *(b_i+1, -E_i+1)* is equal to or more general than the previous state *(b_i, -E_i)*. +E_i+1)* is equal to or more general than the previous state *(b_i, E_i)* +-- more generally, that applying any rule *r* to any state seen in the +sequence leads to generalization, or in formal terms ``r( (b_i, E_i) ) +>= (b_i, E_i)``. We define an annotation state *(b,E)* to be *sound* if for all rules *r* we have ``r( (b,E) ) = (b,E)``. We say that *(b,E)* is *degenerated* if @@ -1525,7 +1532,75 @@ Proof: - XXX +1. The final state *(b_n, E_n)* is sound. + + The proof is based on the fact that the "effect" of any rule only + depends on the annotation of its input and auxiliary variables. + This "effect" is to merge some bindings and/or add some + identifications; it can formalized by saying that ``r( (b,E) ) = + (b,E) union (bf,Ef)`` for a certain *(bf,Ef)* that contains only + the new bindings and identifications. + + More precisely, let *r* be a rule. Let *V_r* be the set of input + and auxiliary variables of *r*, i.e.:: + + V_r = { v | r in Rules_v } + + Let *(b,E)* be a state. Then there exists a state *(bf,Ef)* + representing the "effect" of the rule on *(b,E)* as follows: + + r( (b,E) ) = (b,E) union (bf,Ef) + + and the same *(bf,Ef)* works for any *(b',E')* which is equal to + *(b,E)* on *V_r*:: + + r( (b',E') ) = (b',E') union (bf,Ef) + + This is easily verified on a case-by-case basis for each kind of + rule presented above. The details are left to the reader. + + To show the proposition, we proceed by induction on *i* to show + that each of the meta-states *(S_i, b_i, E_i)* has the following + property: for each rule *r* which is not in *S_i* we have ``r( + (b_i, E_i) ) = (b_i, E_i)``. The result will follow from this + claim because the final *S_n* is empty. + + The claim is trivially true for ``i=0``. Assume that it holds + for some ``i= (bf,Ef) + (b_i+1, E_i+1) >= (b_i, E_i) >= (bf,Ef) + (b_i+1, E_i+1) = (b_i+1, E_i+1) union (bf,Ef) + (b_i+1, E_i+1) = r( (b_i+1, E_i+1) ). + + This concludes the proof. + +2. XXX Complexity From mwh at codespeak.net Fri Oct 28 12:54:06 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 12:54:06 +0200 (CEST) Subject: [pypy-svn] r19109 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028105406.28ACE27BA2@code1.codespeak.net> Author: mwh Date: Fri Oct 28 12:54:05 2005 New Revision: 19109 Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt Log: Tweaks. I think this is good enough now? Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/tech1-submission.txt (original) +++ pypy/extradoc/talk/pycon2006/tech1-submission.txt Fri Oct 28 12:54:05 2005 @@ -1,7 +1,7 @@ Author Names ------------ -(from) Michael Hudson, Holger Krekel, Armin Rigo, Christian Tismer +(from) Michael Hudson, (anyone else?) Contact Information ------------------- @@ -11,7 +11,7 @@ Requested Timeslot ------------------ -45 minutes? Or two 30 minutes? Or? +30 minutes. Summary of proposed presentation -------------------------------- @@ -19,20 +19,22 @@ PyPy, the notorious Python-in-Python project reached a significant milestone in the summer of 2005: being able to produce a standalone python interpreter with no dependencies on any of CPython's C code. + This talk will describe the toolchain that got us to this point and what we plan on doing with it next. Presentation Outline -------------------- -Something like: - - Introduction to PyPy - Demo of pypy-c. - Overview (with the fruit object space again? :) -- Our toolchain: the annotator, the rtyper, the backends. +- Our toolchain: + + the flow object space + + the annotator + + the rtyper + + the backends - Future plans: JIT, logic programming, other backends. -- About the project: The EU, sprints, TDD, etc. Intended audience ----------------- From mwh at codespeak.net Fri Oct 28 12:59:11 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 12:59:11 +0200 (CEST) Subject: [pypy-svn] r19110 - pypy/dist/pypy/tool Message-ID: <20051028105911.13A0427BA2@code1.codespeak.net> Author: mwh Date: Fri Oct 28 12:59:10 2005 New Revision: 19110 Modified: pypy/dist/pypy/tool/asterisk.py Log: add a 'newline at end of file' Modified: pypy/dist/pypy/tool/asterisk.py ============================================================================== --- pypy/dist/pypy/tool/asterisk.py (original) +++ pypy/dist/pypy/tool/asterisk.py Fri Oct 28 12:59:10 2005 @@ -169,4 +169,3 @@ stmts.append(stmt) start = lno self.statements = stmts - \ No newline at end of file From mwh at codespeak.net Fri Oct 28 13:02:58 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 13:02:58 +0200 (CEST) Subject: [pypy-svn] r19111 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028110258.CEDFF27BAA@code1.codespeak.net> Author: mwh Date: Fri Oct 28 13:02:58 2005 New Revision: 19111 Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt Log: Strike mention of future plans. Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/tech1-submission.txt (original) +++ pypy/extradoc/talk/pycon2006/tech1-submission.txt Fri Oct 28 13:02:58 2005 @@ -20,21 +20,20 @@ milestone in the summer of 2005: being able to produce a standalone python interpreter with no dependencies on any of CPython's C code. -This talk will describe the toolchain that got us to this point and -what we plan on doing with it next. +This talk will describe as much of the toolchain that got us to this +point as it's possible to cram into 30 minutes :). Presentation Outline -------------------- -- Introduction to PyPy +- Introduction to PyPy. - Demo of pypy-c. -- Overview (with the fruit object space again? :) -- Our toolchain: - + the flow object space - + the annotator - + the rtyper - + the backends -- Future plans: JIT, logic programming, other backends. +- Overview. +- Our Toolchain: + + The Flow Object Space. + + The Annotator. + + The RTyper. + + The Backend(s) Intended audience ----------------- From mwh at codespeak.net Fri Oct 28 13:04:09 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 13:04:09 +0200 (CEST) Subject: [pypy-svn] r19112 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028110409.6B23627BAA@code1.codespeak.net> Author: mwh Date: Fri Oct 28 13:04:09 2005 New Revision: 19112 Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt Log: more tweaking. Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/tech1-submission.txt (original) +++ pypy/extradoc/talk/pycon2006/tech1-submission.txt Fri Oct 28 13:04:09 2005 @@ -1,12 +1,13 @@ Author Names ------------ -(from) Michael Hudson, (anyone else?) +Michael Hudson (anyone else?) Contact Information ------------------- -pypy-dev? +pypy-dev at codespeak.net <- preferred. +mwh at python.net <- if the above is unacceptable for some reason. Requested Timeslot ------------------ From hpk at codespeak.net Fri Oct 28 13:06:02 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 28 Oct 2005 13:06:02 +0200 (CEST) Subject: [pypy-svn] r19113 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028110602.E303927BAA@code1.codespeak.net> Author: hpk Date: Fri Oct 28 13:06:00 2005 New Revision: 19113 Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt Log: only talk about low level backends here? Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/tech1-submission.txt (original) +++ pypy/extradoc/talk/pycon2006/tech1-submission.txt Fri Oct 28 13:06:00 2005 @@ -34,7 +34,7 @@ + The Flow Object Space. + The Annotator. + The RTyper. - + The Backend(s) + + The low level backend(s) Intended audience ----------------- From bea at codespeak.net Fri Oct 28 13:07:59 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Fri, 28 Oct 2005 13:07:59 +0200 (CEST) Subject: [pypy-svn] r19115 - pypy/extradoc/talk Message-ID: <20051028110759.7235B27BA8@code1.codespeak.net> Author: bea Date: Fri Oct 28 13:07:57 2005 New Revision: 19115 Added: pypy/extradoc/talk/pypy_agiletalk_pmi20051027.sxi (contents, props changed) Log: the talk I did yesterday in Link?ping, PMI Added: pypy/extradoc/talk/pypy_agiletalk_pmi20051027.sxi ============================================================================== Binary file. No diff available. From mwh at codespeak.net Fri Oct 28 13:09:21 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 13:09:21 +0200 (CEST) Subject: [pypy-svn] r19116 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028110921.E8F6D27BAA@code1.codespeak.net> Author: mwh Date: Fri Oct 28 13:09:21 2005 New Revision: 19116 Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt Log: pedantry Modified: pypy/extradoc/talk/pycon2006/tech1-submission.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/tech1-submission.txt (original) +++ pypy/extradoc/talk/pycon2006/tech1-submission.txt Fri Oct 28 13:09:21 2005 @@ -34,7 +34,7 @@ + The Flow Object Space. + The Annotator. + The RTyper. - + The low level backend(s) + + The Low Level Backend(s). Intended audience ----------------- From mwh at codespeak.net Fri Oct 28 13:25:43 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 13:25:43 +0200 (CEST) Subject: [pypy-svn] r19117 - pypy/dist/pypy/module/recparser Message-ID: <20051028112543.6198F27BA8@code1.codespeak.net> Author: mwh Date: Fri Oct 28 13:25:42 2005 New Revision: 19117 Modified: pypy/dist/pypy/module/recparser/codegen.py Log: Repair SyntaxError. What is this file for? Modified: pypy/dist/pypy/module/recparser/codegen.py ============================================================================== --- pypy/dist/pypy/module/recparser/codegen.py (original) +++ pypy/dist/pypy/module/recparser/codegen.py Fri Oct 28 13:25:42 2005 @@ -129,7 +129,7 @@ self.setups.append((self.LOOP, loop)) node.test.visit(self) - self.emit(CondJump('IF_FALSE', else_or after)) + self.emit(CondJump('IF_FALSE', else_or, after)) self.nextBlock() self.emit(PopTop()) From mwh at codespeak.net Fri Oct 28 13:26:55 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 13:26:55 +0200 (CEST) Subject: [pypy-svn] r19118 - pypy/dist/pypy/tool Message-ID: <20051028112655.87DB027BA8@code1.codespeak.net> Author: mwh Date: Fri Oct 28 13:26:54 2005 New Revision: 19118 Modified: pypy/dist/pypy/tool/importfun.py Log: support more styles of import statement. Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Fri Oct 28 13:26:54 2005 @@ -137,6 +137,7 @@ self.toplevelscope = Scope() self.importers = [] def import_(self, modname): + # should probably handle relative imports here. if modname not in self._imports: if recursive and modname not in self.system.modules: self.system.pendingmodules[modname] = None @@ -205,19 +206,21 @@ # this is the 'import foo' case r.import_(modname) - postop, postoparg = opcodes[i+1] - - # ban 'import foo.bar' (it's dubious style anyway, imho) - - #assert not '.' in modname - - # this assert actually triggers quite frequently, for things like - # import py.lib as lib - # (which is strange code, in my book...) + seenloadattr = False + while 1: + postop, postoparg = opcodes[i+1] + i += 1 + if postop != _op_.LOAD_ATTR: + break + seenloadattr = True + assert postop in storeops, 'postop' + storename = name_for_op(codeob, postop, postoparg) - scope.modvars[storename] = modname.split('.')[0] - i += 1 + if seenloadattr: + scope.modvars[storename] = modname + else: + scope.modvars[storename] = modname.split('.')[0] elif fromlist == ('*',): assert toplevel, 'toplevel' if modname.startswith('pypy.'): @@ -264,7 +267,9 @@ submod = modname + '.' + f r.import_(submod) + op, oparg = opcodes[i] + i += 1 assert op in storeops, 'opstore' storename = name_for_op(codeob, op, oparg) @@ -273,7 +278,7 @@ scope.modvars[storename] = submod else: scope.varsources[storename] = modname, f - i += 1 + op, oparg = opcodes[i] assert op == _op_.POP_TOP, 'POP_TOP' elif op == _op_.STORE_NAME and toplevel or op == _op_.STORE_GLOBAL: @@ -307,6 +312,16 @@ for c in codeobjs: process(r, c, Scope(scope)) +def find_from_dotted_name(modname): + path = None + for part in modname.split('.'): + try: + path = [imp.find_module(part, path)[1]] + except ImportError: + print modname + raise + return path[0] + def process_module(dottedname, system): if dottedname.endswith('.py'): path = dottedname @@ -339,15 +354,7 @@ return r -def find_from_dotted_name(modname): - path = None - for part in modname.split('.'): - try: - path = [imp.find_module(part, path)[1]] - except ImportError: - print modname - raise - return path[0] +# --- stuff that uses the processed data --- def report_unused_symbols(system): for name, mod in sorted(system.modules.iteritems()): @@ -463,6 +470,7 @@ if m._imports['pypy.interpreter.pycode'].get('CO_VARARGS') == True: print m.name +# --- HTML generation stuff --- def file_for_module(module): fname = os.path.join('importfunhtml', *module.name.split('.')) + '.html' @@ -580,6 +588,8 @@ for m in system.modules.itervalues(): html_for_module(m) +# --- the driver stuff! --- + def main(*paths): system = System() From mwh at codespeak.net Fri Oct 28 13:29:04 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 13:29:04 +0200 (CEST) Subject: [pypy-svn] r19119 - pypy/dist/pypy/tool Message-ID: <20051028112904.324E927BA8@code1.codespeak.net> Author: mwh Date: Fri Oct 28 13:29:03 2005 New Revision: 19119 Modified: pypy/dist/pypy/tool/importfun.py Log: be somewhat more confident. Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Fri Oct 28 13:29:03 2005 @@ -342,7 +342,7 @@ try: code = compile(open(path, "U").read(), path, 'exec') process(r, code, r.toplevelscope, True) - except (ImportError, AssertionError, SyntaxError), e: + except (ImportError, SyntaxError), e: print "failed!", e #raise else: From arigo at codespeak.net Fri Oct 28 13:41:09 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Oct 2005 13:41:09 +0200 (CEST) Subject: [pypy-svn] r19120 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028114109.4EE2027BA2@code1.codespeak.net> Author: arigo Date: Fri Oct 28 13:41:07 2005 New Revision: 19120 Modified: pypy/extradoc/talk/pycon2006/pypy-archsession.txt Log: Inserted (starting autumn 2005) Modified: pypy/extradoc/talk/pycon2006/pypy-archsession.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pypy-archsession.txt (original) +++ pypy/extradoc/talk/pycon2006/pypy-archsession.txt Fri Oct 28 13:41:07 2005 @@ -16,15 +16,15 @@ Summary of proposed presentation -------------------------------- -After reaching important milestones, the PyPy project is -now heading towards building a specializing JIT-compiler, -stackless features and translation to higher level languages -into the code base. In this session we will present -and interactively discuss with the audience basic -architectural pictures. We'd are going to emphasize the -various emerging possibilities for further development -part of which will be an ongoing effort of the -European Union's funded part of the PyPy project. +After reaching important milestones, the PyPy project is now +(starting autumn 2005) heading towards building a specializing +JIT-compiler, stackless features and translation to higher +level languages into the code base. In this session we will +present and interactively discuss with the audience basic +architectural pictures. We'd are going to emphasize the +various emerging possibilities for further development part of +which will be an ongoing effort of the European Union's funded +part of the PyPy project. Presentation Outline -------------------- From mwh at codespeak.net Fri Oct 28 13:48:25 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Fri, 28 Oct 2005 13:48:25 +0200 (CEST) Subject: [pypy-svn] r19121 - pypy/dist/pypy/tool Message-ID: <20051028114825.27DAC27BA8@code1.codespeak.net> Author: mwh Date: Fri Oct 28 13:48:24 2005 New Revision: 19121 Modified: pypy/dist/pypy/tool/importfun.py Log: more insanity reduction Modified: pypy/dist/pypy/tool/importfun.py ============================================================================== --- pypy/dist/pypy/tool/importfun.py (original) +++ pypy/dist/pypy/tool/importfun.py Fri Oct 28 13:48:24 2005 @@ -255,29 +255,21 @@ i += 1 continue - var = mod = None + op, oparg = opcodes[i] + i += 1 + + assert op in storeops, 'opstore' + storename = name_for_op(codeob, op, oparg) try: imp.find_module(f, path) except ImportError: - var = True r.import_(modname)[f] = False + scope.varsources[storename] = modname, f else: - mod = True submod = modname + '.' + f r.import_(submod) - - - op, oparg = opcodes[i] - i += 1 - - assert op in storeops, 'opstore' - storename = name_for_op(codeob, op, oparg) - - if mod: scope.modvars[storename] = submod - else: - scope.varsources[storename] = modname, f op, oparg = opcodes[i] assert op == _op_.POP_TOP, 'POP_TOP' From arigo at codespeak.net Fri Oct 28 13:52:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Oct 2005 13:52:08 +0200 (CEST) Subject: [pypy-svn] r19122 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028115208.1C42E27BAA@code1.codespeak.net> Author: arigo Date: Fri Oct 28 13:52:06 2005 New Revision: 19122 Modified: pypy/extradoc/talk/pycon2006/pylib.txt Log: Typos Modified: pypy/extradoc/talk/pycon2006/pylib.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pylib.txt (original) +++ pypy/extradoc/talk/pycon2006/pylib.txt Fri Oct 28 13:52:06 2005 @@ -39,7 +39,7 @@ a number of other projects have adapted its methods. We plan to give usage examples for various parts of the py library. The current key parts of the py lib -we are to present: +we will present are: - py.log: keyword & subscription based lazy logging - py.compat: use newer standard library modules from older @@ -63,4 +63,4 @@ ----------------- All python developers (who are interested in lightweight libraries and -lean pythonnic APIs in order to support agile development). +lean pythonic APIs in order to support agile development). From hpk at codespeak.net Fri Oct 28 13:55:56 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 28 Oct 2005 13:55:56 +0200 (CEST) Subject: [pypy-svn] r19123 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028115556.1FD4327BA8@code1.codespeak.net> Author: hpk Date: Fri Oct 28 13:55:52 2005 New Revision: 19123 Added: pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt - copied, changed from r19122, pypy/extradoc/talk/pycon2006/tech1-submission.txt Removed: pypy/extradoc/talk/pycon2006/tech1-submission.txt Modified: pypy/extradoc/talk/pycon2006/pypy-archsession.txt Log: putting names on the talks some refinements renamed tech1 to "pypy-selfcontained" to be more descriptive Modified: pypy/extradoc/talk/pycon2006/pypy-archsession.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pypy-archsession.txt (original) +++ pypy/extradoc/talk/pycon2006/pypy-archsession.txt Fri Oct 28 13:55:52 2005 @@ -1,17 +1,20 @@ Author Names ------------ -(from) Michael Hudson, Holger Krekel, Armin Rigo, Christian Tismer +(from) Holger Krekel, Armin Rigo Contact Information ------------------- -pypy-dev? +pypy-dev at codespeak.net (developer mailing list) +arigo at tunes.org +hpk at merlinux.de Requested Timeslot ------------------ -45 minutes or 30 minutes. both possible. +45 minutes or 30 minutes. both possible (the talk can be considered +a kind of tutorial on PyPy architectural pictures). Summary of proposed presentation -------------------------------- @@ -35,7 +38,7 @@ - Language Implementation: Bytecode Interpreter and Object Space interaction - Translation to low level languages (C/LLVM) - Translation to higher level languages (e.g. Squeak/Java) -- JIT-compiler architecture (very-low-level interpreter) +- JIT-compiler architecture (very-low-level/l3 interpreter) - Interweaving of Garbage Collection, threading and stackless operations into the translation process From hpk at codespeak.net Fri Oct 28 14:32:09 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Fri, 28 Oct 2005 14:32:09 +0200 (CEST) Subject: [pypy-svn] r19125 - pypy/extradoc/talk/pycon2006 Message-ID: <20051028123209.01F3D27BAA@code1.codespeak.net> Author: hpk Date: Fri Oct 28 14:32:08 2005 New Revision: 19125 Modified: pypy/extradoc/talk/pycon2006/pylib.txt Log: kind of finalizing the py lib tutorial suggestion adding armin as co-speaker Modified: pypy/extradoc/talk/pycon2006/pylib.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pylib.txt (original) +++ pypy/extradoc/talk/pycon2006/pylib.txt Fri Oct 28 14:32:08 2005 @@ -1,12 +1,13 @@ Author Names ------------ -(from) Holger Krekel +(from) Holger Krekel, Armin Rigo Contact Information ------------------- holger krekel +py-dev at codespeak.net (py lib developers list) Requested Timeslot ------------------ @@ -18,10 +19,10 @@ Title: using the py library (apart from py.test) -Already known for its widely used "py.test" testing tool, the +Already known for the widely used py.test tool, the "py lib" has more to offer. We are going to explore the -experimental package "name export mechanism" involving lazy -imports, a lightweight tag/keyword-based logging scheme, +experimental package "name export mechanism" which involves +lazy imports, a lightweight tag/keyword-based logging scheme, subversion and local Path objects and compatibility modules that make recent Python library modules uniformly available from older Python versions. We also will glance into the current state of @@ -57,10 +58,10 @@ - extending/refactoring py.path to support in-memory and other filesystems - integrating twisted testing functionality into py.test -- release plan +- a release plan Intended audience ----------------- All python developers (who are interested in lightweight libraries and -lean pythonic APIs in order to support agile development). +lean pythonic APIs in order to support agile development) From pedronis at codespeak.net Fri Oct 28 14:37:39 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 28 Oct 2005 14:37:39 +0200 (CEST) Subject: [pypy-svn] r19126 - pypy/release/0.8.x Message-ID: <20051028123739.874E327BA8@code1.codespeak.net> Author: pedronis Date: Fri Oct 28 14:37:38 2005 New Revision: 19126 Added: pypy/release/0.8.x/ - copied from r19125, pypy/dist/ Log: creating release 0.8 branch From arigo at codespeak.net Fri Oct 28 14:48:07 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Fri, 28 Oct 2005 14:48:07 +0200 (CEST) Subject: [pypy-svn] r19127 - pypy/dist/pypy/doc Message-ID: <20051028124807.EE05427BB4@code1.codespeak.net> Author: arigo Date: Fri Oct 28 14:48:05 2005 New Revision: 19127 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: working... Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Fri Oct 28 14:48:05 2005 @@ -851,7 +851,12 @@ are replaced by the variables that really appear in each particular ``add`` operation in the flow graphs of the user program):: - z=add(x,y), Bool<=b(x)<=Int, Bool<=b(y)<=Int + z=add(x,y), b(x)=Int, Bool<=b(y)<=Int + ------------------------------------------------------ + b' = b with (z->Int) + + + z=add(x,y), Bool<=b(x)<=Int, b(y)=Int ------------------------------------------------------ b' = b with (z->Int) @@ -872,10 +877,8 @@ derived from the current state -- here by changing the binding of the result variable *z*. -Note that for conciseness, we omitted the guards in the first rule that -prevent it from being applied if the second rule (which is more precise) -applies as well. As none of these rules modify *E*, we also omitted the -``E'=E``. +Note that for conciseness we omitted the ``E'=E`` (none of these rules +modify *E*). Also ``[note]`` that we do not generally try to prove the correctness and safety of the user program, preferring to rely on test coverage for @@ -1565,13 +1568,13 @@ (b_i, E_i) ) = (b_i, E_i)``. The result will follow from this claim because the final *S_n* is empty. - The claim is trivially true for ``i=0``. Assume that it holds - for some ``iInt``. We must show + that ``bs(z) >= Int``. To do so, consider that for + non-degenerated states the guards of the above rule are + equivalent to ``b(x)>=Int, b(y)>=Bool``. As *z* is not the same + variable as *x* or *y*, we know from ``(b_i, E_i) <= (bs,Es)`` + that ``bs(x)>=Int`` and ``bs(y)>=Bool``. Moreover, by definition + ``r( (bs,Es) ) = (bs,Es)``. We conclude that ``bs(z)=Int``. + + XXX Complexity From pedronis at codespeak.net Fri Oct 28 23:12:56 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 28 Oct 2005 23:12:56 +0200 (CEST) Subject: [pypy-svn] r19131 - in pypy/dist/pypy: doc/weekly translator/asm/ppcgen Message-ID: <20051028211256.35D0027B9F@code1.codespeak.net> Author: pedronis Date: Fri Oct 28 23:12:55 2005 New Revision: 19131 Modified: pypy/dist/pypy/doc/weekly/ (props changed) pypy/dist/pypy/translator/asm/ppcgen/ (props changed) Log: adjust svn:ignore From pedronis at codespeak.net Fri Oct 28 23:16:16 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Fri, 28 Oct 2005 23:16:16 +0200 (CEST) Subject: [pypy-svn] r19132 - in pypy/release/0.8.x/pypy: doc/weekly translator/asm/ppcgen Message-ID: <20051028211616.7F2EF27BA2@code1.codespeak.net> Author: pedronis Date: Fri Oct 28 23:16:15 2005 New Revision: 19132 Modified: pypy/release/0.8.x/pypy/doc/weekly/ (props changed) pypy/release/0.8.x/pypy/translator/asm/ppcgen/ (props changed) Log: merge svn:ignore changes (rev 19131) from trunk From pedronis at codespeak.net Sat Oct 29 00:08:41 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 29 Oct 2005 00:08:41 +0200 (CEST) Subject: [pypy-svn] r19133 - pypy/dist/pypy/translator/c/test Message-ID: <20051028220841.66E1127B99@code1.codespeak.net> Author: pedronis Date: Sat Oct 29 00:08:40 2005 New Revision: 19133 Added: pypy/dist/pypy/translator/c/test/test_ext__socket.py - copied, changed from r19130, pypy/dist/pypy/translator/c/test/test_extfunc.py Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py Log: split socket ext function tests in a different file (it probably make sense anyway instead of having a evergrowing test_extfunc, especially more delicate unstable additional ext funcs) 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 Sat Oct 29 00:08:40 2005 @@ -1,6 +1,6 @@ import autopath import py -import os, time, sys, _socket +import os, time, sys from pypy.tool.udir import udir from pypy.translator.c.test.test_genc import compile from pypy.translator.c.extfunc import EXTERNALS @@ -532,60 +532,3 @@ compared_with.sort() assert result == compared_with -def test_htonl(): - import pypy.module._socket.rpython.exttable # for declare()/declaretype() - # This just checks that htons etc. are their own inverse, - # when looking at the lower 16 or 32 bits. - def fn1(n): - return _socket.htonl(n) - def fn2(n): - return _socket.ntohl(n) - def fn3(n): - return _socket.ntohs(n) - def fn4(n): - return _socket.htons(n) - sizes = {compile(fn1, [int]): 32, compile(fn2, [int]): 32, - compile(fn4, [int]): 16, compile(fn3, [int]): 16} - for func, size in sizes.items(): - mask = (1L< Author: pedronis Date: Sat Oct 29 00:10:54 2005 New Revision: 19134 Added: pypy/release/0.8.x/pypy/translator/c/test/test_ext__socket.py - copied unchanged from r19133, pypy/dist/pypy/translator/c/test/test_ext__socket.py Modified: pypy/release/0.8.x/pypy/translator/c/test/test_extfunc.py Log: merge splitting out of _socket ext func tests (rev 19133) Modified: pypy/release/0.8.x/pypy/translator/c/test/test_extfunc.py ============================================================================== --- pypy/release/0.8.x/pypy/translator/c/test/test_extfunc.py (original) +++ pypy/release/0.8.x/pypy/translator/c/test/test_extfunc.py Sat Oct 29 00:10:54 2005 @@ -1,6 +1,6 @@ import autopath import py -import os, time, sys, _socket +import os, time, sys from pypy.tool.udir import udir from pypy.translator.c.test.test_genc import compile from pypy.translator.c.extfunc import EXTERNALS @@ -532,60 +532,3 @@ compared_with.sort() assert result == compared_with -def test_htonl(): - import pypy.module._socket.rpython.exttable # for declare()/declaretype() - # This just checks that htons etc. are their own inverse, - # when looking at the lower 16 or 32 bits. - def fn1(n): - return _socket.htonl(n) - def fn2(n): - return _socket.ntohl(n) - def fn3(n): - return _socket.ntohs(n) - def fn4(n): - return _socket.htons(n) - sizes = {compile(fn1, [int]): 32, compile(fn2, [int]): 32, - compile(fn4, [int]): 16, compile(fn3, [int]): 16} - for func, size in sizes.items(): - mask = (1L< Author: pedronis Date: Sat Oct 29 00:23:11 2005 New Revision: 19135 Modified: pypy/release/0.8.x/pypy/module/_socket/rpython/test/test_ll__socket.py pypy/release/0.8.x/pypy/module/_socket/test/test_socket2.py pypy/release/0.8.x/pypy/translator/c/test/test_ext__socket.py Log: skipping in-progress/unstable socket tests on the branch for the 0.8 release Modified: pypy/release/0.8.x/pypy/module/_socket/rpython/test/test_ll__socket.py ============================================================================== --- pypy/release/0.8.x/pypy/module/_socket/rpython/test/test_ll__socket.py (original) +++ pypy/release/0.8.x/pypy/module/_socket/rpython/test/test_ll__socket.py Sat Oct 29 00:23:11 2005 @@ -1,4 +1,4 @@ - +import py import _socket import pypy.module._socket.rpython.exttable from pypy.module._socket.rpython.ll__socket import * @@ -7,6 +7,9 @@ from pypy.rpython.module.support import from_rstr from pypy.rpython.module.support import to_opaque_object, from_opaque_object +def setup_module(mod): + py.test.skip("As of 0.8 developement in-progress.") + def test_ntohs(): def fn(): return _socket.ntohs(1) Modified: pypy/release/0.8.x/pypy/module/_socket/test/test_socket2.py ============================================================================== --- pypy/release/0.8.x/pypy/module/_socket/test/test_socket2.py (original) +++ pypy/release/0.8.x/pypy/module/_socket/test/test_socket2.py Sat Oct 29 00:23:11 2005 @@ -4,6 +4,7 @@ import socket, sys def setup_module(mod): + py.test.skip("As of 0.8 developement in-progress.") mod.space = StdObjSpace(usemodules=['_socket']) mod.w_socket = space.appexec([], "(): import _socket as m; return m") mod.path = udir.join('fd') Modified: pypy/release/0.8.x/pypy/translator/c/test/test_ext__socket.py ============================================================================== --- pypy/release/0.8.x/pypy/translator/c/test/test_ext__socket.py (original) +++ pypy/release/0.8.x/pypy/translator/c/test/test_ext__socket.py Sat Oct 29 00:23:11 2005 @@ -4,6 +4,7 @@ from pypy.translator.c.test.test_genc import compile def setup_module(mod): + py.test.skip("As of 0.8 developement in-progress.") import pypy.module._socket.rpython.exttable # for declare()/declaretype() def test_htonl(): From pedronis at codespeak.net Sat Oct 29 00:51:41 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 29 Oct 2005 00:51:41 +0200 (CEST) Subject: [pypy-svn] r19136 - pypy/dist/lib-python/modified-2.4.1/test Message-ID: <20051028225141.0548B27B9F@code1.codespeak.net> Author: pedronis Date: Sat Oct 29 00:51:41 2005 New Revision: 19136 Modified: pypy/dist/lib-python/modified-2.4.1/test/test_repr.py Log: our builtin method/function are mostly like conventional functions, so we cannot reasonably have separate repr, in Paris we converged to the idea that is more important to have the repr consistent with the one for normal user functions/methods. Adjust this test to pass again with the changes that were made there. Modified: pypy/dist/lib-python/modified-2.4.1/test/test_repr.py ============================================================================== --- pypy/dist/lib-python/modified-2.4.1/test/test_repr.py (original) +++ pypy/dist/lib-python/modified-2.4.1/test/test_repr.py Sat Oct 29 00:51:41 2005 @@ -135,7 +135,7 @@ eq(repr(hash), '') # Methods self.failUnless(repr(''.split).find( - 'method split of str object at 0x') > -1) + "bound method str.split of '' at 0x") > -1) def test_xrange(self): import warnings @@ -174,7 +174,7 @@ def test_descriptors(self): eq = self.assertEquals # method descriptors - eq(repr(dict.items), "") + eq(repr(dict.items), "") # XXX member descriptors # XXX attribute descriptors # XXX slot descriptors From pedronis at codespeak.net Sat Oct 29 00:54:14 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 29 Oct 2005 00:54:14 +0200 (CEST) Subject: [pypy-svn] r19137 - pypy/release/0.8.x/lib-python/modified-2.4.1/test Message-ID: <20051028225414.23EE827BA0@code1.codespeak.net> Author: pedronis Date: Sat Oct 29 00:54:13 2005 New Revision: 19137 Modified: pypy/release/0.8.x/lib-python/modified-2.4.1/test/test_repr.py Log: merge fix for test_repr (rev 19136), be consistent with user defined func/meth reprs Modified: pypy/release/0.8.x/lib-python/modified-2.4.1/test/test_repr.py ============================================================================== --- pypy/release/0.8.x/lib-python/modified-2.4.1/test/test_repr.py (original) +++ pypy/release/0.8.x/lib-python/modified-2.4.1/test/test_repr.py Sat Oct 29 00:54:13 2005 @@ -135,7 +135,7 @@ eq(repr(hash), '') # Methods self.failUnless(repr(''.split).find( - 'method split of str object at 0x') > -1) + "bound method str.split of '' at 0x") > -1) def test_xrange(self): import warnings @@ -174,7 +174,7 @@ def test_descriptors(self): eq = self.assertEquals # method descriptors - eq(repr(dict.items), "") + eq(repr(dict.items), "") # XXX member descriptors # XXX attribute descriptors # XXX slot descriptors From pedronis at codespeak.net Sat Oct 29 01:35:33 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 29 Oct 2005 01:35:33 +0200 (CEST) Subject: [pypy-svn] r19138 - in pypy/dist/pypy/interpreter: . test Message-ID: <20051028233533.3291D27B99@code1.codespeak.net> Author: pedronis Date: Sat Oct 29 01:35:30 2005 New Revision: 19138 Modified: pypy/dist/pypy/interpreter/function.py pypy/dist/pypy/interpreter/test/test_function.py Log: reject None as closure parameter if the code wants a closure. make compliancy test_new pass again. Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Sat Oct 29 01:35:30 2005 @@ -63,7 +63,8 @@ defs_w = space.unpackiterable(w_argdefs) else: defs_w = [] - if space.is_w(w_closure, space.w_None): + nfreevars = len(code.co_freevars) + if space.is_w(w_closure, space.w_None) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -72,9 +73,9 @@ from pypy.interpreter.nestedscope import Cell closure_w = space.unpackiterable(w_closure) n = len(closure_w) - if not isinstance(code, PyCode) or len(code.co_freevars) == 0: + if not isinstance(code, PyCode) or nfreevars == 0: raise OperationError(space.w_ValueError, space.wrap("no closure needed")) - elif len(code.co_freevars) != n: + elif nfreevars != n: raise OperationError(space.w_ValueError, space.wrap("closure is wrong size")) closure = [] for w_cell in closure_w: Modified: pypy/dist/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/dist/pypy/interpreter/test/test_function.py (original) +++ pypy/dist/pypy/interpreter/test/test_function.py Sat Oct 29 01:35:30 2005 @@ -61,6 +61,13 @@ f2 = FuncType(f.func_code, f.func_globals, 'f2', None, None) assert f2() == 42 + def g(x): + def f(): + return x + return f + f = g(42) + raises(TypeError, FuncType, f.func_code, f.func_globals, 'f2', None, None) + class AppTestFunction: def test_simple_call(self): def func(arg1, arg2): From pedronis at codespeak.net Sat Oct 29 01:38:08 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 29 Oct 2005 01:38:08 +0200 (CEST) Subject: [pypy-svn] r19139 - in pypy/release/0.8.x/pypy/interpreter: . test Message-ID: <20051028233808.C858C27B9A@code1.codespeak.net> Author: pedronis Date: Sat Oct 29 01:38:07 2005 New Revision: 19139 Modified: pypy/release/0.8.x/pypy/interpreter/function.py pypy/release/0.8.x/pypy/interpreter/test/test_function.py Log: merge fix for test_new.py (rev 19138). Modified: pypy/release/0.8.x/pypy/interpreter/function.py ============================================================================== --- pypy/release/0.8.x/pypy/interpreter/function.py (original) +++ pypy/release/0.8.x/pypy/interpreter/function.py Sat Oct 29 01:38:07 2005 @@ -63,7 +63,8 @@ defs_w = space.unpackiterable(w_argdefs) else: defs_w = [] - if space.is_w(w_closure, space.w_None): + nfreevars = len(code.co_freevars) + if space.is_w(w_closure, space.w_None) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) @@ -72,9 +73,9 @@ from pypy.interpreter.nestedscope import Cell closure_w = space.unpackiterable(w_closure) n = len(closure_w) - if not isinstance(code, PyCode) or len(code.co_freevars) == 0: + if not isinstance(code, PyCode) or nfreevars == 0: raise OperationError(space.w_ValueError, space.wrap("no closure needed")) - elif len(code.co_freevars) != n: + elif nfreevars != n: raise OperationError(space.w_ValueError, space.wrap("closure is wrong size")) closure = [] for w_cell in closure_w: Modified: pypy/release/0.8.x/pypy/interpreter/test/test_function.py ============================================================================== --- pypy/release/0.8.x/pypy/interpreter/test/test_function.py (original) +++ pypy/release/0.8.x/pypy/interpreter/test/test_function.py Sat Oct 29 01:38:07 2005 @@ -61,6 +61,13 @@ f2 = FuncType(f.func_code, f.func_globals, 'f2', None, None) assert f2() == 42 + def g(x): + def f(): + return x + return f + f = g(42) + raises(TypeError, FuncType, f.func_code, f.func_globals, 'f2', None, None) + class AppTestFunction: def test_simple_call(self): def func(arg1, arg2): From pedronis at codespeak.net Sat Oct 29 04:54:38 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sat, 29 Oct 2005 04:54:38 +0200 (CEST) Subject: [pypy-svn] r19140 - pypy/dist/pypy/interpreter/pyparser Message-ID: <20051029025438.AC19B27B99@code1.codespeak.net> Author: pedronis Date: Sat Oct 29 04:54:36 2005 New Revision: 19140 Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py pypy/dist/pypy/interpreter/pyparser/grammar.py Log: address astcompiler speed problems with e.g. large [...] constructions. Given that the parser is recursive descent the change should be safe. Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original) +++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Sat Oct 29 04:54:36 2005 @@ -1041,7 +1041,7 @@ else: lineno = -1 builder.push(ast.List(nodes, lineno)) - + def build_decorator(builder, nb): """decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE""" @@ -1614,7 +1614,8 @@ class AstBuilderContext(AbstractContext): """specific context management for AstBuidler""" def __init__(self, rule_stack): - self.rule_stack = list(rule_stack) + #self.rule_stack = list(rule_stack) + self.d = len(rule_stack) class AstBuilder(BaseGrammarBuilder): """A builder that directly produce the AST""" @@ -1632,7 +1633,9 @@ ## if DEBUG_MODE: ## print "Restoring context (%s)" % (len(ctx.rule_stack)) assert isinstance(ctx, AstBuilderContext) - self.rule_stack = ctx.rule_stack + assert len(self.rule_stack) >= ctx.d + del self.rule_stack[ctx.d:] + #self.rule_stack = ctx.rule_stack def pop(self): return self.rule_stack.pop(-1) @@ -1657,7 +1660,7 @@ def alternative( self, rule, source ): # Do nothing, keep rule on top of the stack - rule_stack = self.rule_stack[:] +## rule_stack = self.rule_stack[:] if rule.is_root(): ## if DEBUG_MODE: ## print "ALT:", sym.sym_name[rule.codename], self.rule_stack @@ -1678,7 +1681,7 @@ def sequence(self, rule, source, elts_number): """ """ - rule_stack = self.rule_stack[:] +## rule_stack = self.rule_stack[:] if rule.is_root(): ## if DEBUG_MODE: ## print "SEQ:", sym.sym_name[rule.codename] Modified: pypy/dist/pypy/interpreter/pyparser/grammar.py ============================================================================== --- pypy/dist/pypy/interpreter/pyparser/grammar.py (original) +++ pypy/dist/pypy/interpreter/pyparser/grammar.py Sat Oct 29 04:54:36 2005 @@ -536,8 +536,11 @@ """ if DEBUG > 1: print "try kle:", self.display() - ctx = source.context() - bctx = builder.context() + ctx = 0 + bctx = None + if self.min: + ctx = source.context() + bctx = builder.context() rules = 0 rule = self.args[0] while True: From pedronis at codespeak.net Sun Oct 30 00:37:41 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 30 Oct 2005 00:37:41 +0200 (CEST) Subject: [pypy-svn] r19171 - pypy/dist/pypy/interpreter Message-ID: <20051029223741.C973827B6E@code1.codespeak.net> Author: pedronis Date: Sun Oct 30 00:37:40 2005 New Revision: 19171 Modified: pypy/dist/pypy/interpreter/function.py Log: oops, don't have co_freevars move up Modified: pypy/dist/pypy/interpreter/function.py ============================================================================== --- pypy/dist/pypy/interpreter/function.py (original) +++ pypy/dist/pypy/interpreter/function.py Sun Oct 30 00:37:40 2005 @@ -63,17 +63,19 @@ defs_w = space.unpackiterable(w_argdefs) else: defs_w = [] - nfreevars = len(code.co_freevars) + nfreevars = 0 + from pypy.interpreter.pycode import PyCode + if isinstance(code, PyCode): + nfreevars = len(code.co_freevars) if space.is_w(w_closure, space.w_None) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) else: - from pypy.interpreter.pycode import PyCode from pypy.interpreter.nestedscope import Cell closure_w = space.unpackiterable(w_closure) n = len(closure_w) - if not isinstance(code, PyCode) or nfreevars == 0: + if nfreevars == 0: raise OperationError(space.w_ValueError, space.wrap("no closure needed")) elif nfreevars != n: raise OperationError(space.w_ValueError, space.wrap("closure is wrong size")) From pedronis at codespeak.net Sun Oct 30 01:40:16 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 30 Oct 2005 01:40:16 +0200 (CEST) Subject: [pypy-svn] r19172 - pypy/release/0.8.x/pypy/interpreter Message-ID: <20051029234016.D049227B71@code1.codespeak.net> Author: pedronis Date: Sun Oct 30 01:40:15 2005 New Revision: 19172 Modified: pypy/release/0.8.x/pypy/interpreter/function.py Log: merge 19171, don't have co_freevars bubble up Modified: pypy/release/0.8.x/pypy/interpreter/function.py ============================================================================== --- pypy/release/0.8.x/pypy/interpreter/function.py (original) +++ pypy/release/0.8.x/pypy/interpreter/function.py Sun Oct 30 01:40:15 2005 @@ -63,17 +63,19 @@ defs_w = space.unpackiterable(w_argdefs) else: defs_w = [] - nfreevars = len(code.co_freevars) + nfreevars = 0 + from pypy.interpreter.pycode import PyCode + if isinstance(code, PyCode): + nfreevars = len(code.co_freevars) if space.is_w(w_closure, space.w_None) and nfreevars == 0: closure = None elif not space.is_w(space.type(w_closure), space.w_tuple): raise OperationError(space.w_TypeError, space.wrap("invalid closure")) else: - from pypy.interpreter.pycode import PyCode from pypy.interpreter.nestedscope import Cell closure_w = space.unpackiterable(w_closure) n = len(closure_w) - if not isinstance(code, PyCode) or nfreevars == 0: + if nfreevars == 0: raise OperationError(space.w_ValueError, space.wrap("no closure needed")) elif nfreevars != n: raise OperationError(space.w_ValueError, space.wrap("closure is wrong size")) From pedronis at codespeak.net Sun Oct 30 01:56:18 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 30 Oct 2005 01:56:18 +0200 (CEST) Subject: [pypy-svn] r19173 - in pypy/dist/pypy/translator: . c goal Message-ID: <20051029235618.B322027B71@code1.codespeak.net> Author: pedronis Date: Sun Oct 30 01:56:16 2005 New Revision: 19173 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/goal/driver.py pypy/dist/pypy/translator/goal/targetpypystandalone.py pypy/dist/pypy/translator/goal/translate_pypy.py pypy/dist/pypy/translator/translator.py Log: - concrete support for target specific arguments/options - add --thread option to targetpypystandalone to have threads explicitly enabled, for now this is disabled because a thread-safe stack_too_big is needed to have working thread again GcPolicies now take a thread_enabled flag so that they can do what is necessary for thread support. Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Sun Oct 30 01:56:16 2005 @@ -14,7 +14,7 @@ class LowLevelDatabase: - def __init__(self, translator=None, standalone=False, gcpolicy=None): + def __init__(self, translator=None, standalone=False, gcpolicy=None, thread_enabled=False): self.translator = translator self.standalone = standalone self.structdefnodes = {} @@ -31,7 +31,7 @@ if gcpolicy is None: from pypy.translator.c import gc gcpolicy = gc.RefcountingGcPolicy - self.gcpolicy = gcpolicy(self) + self.gcpolicy = gcpolicy(self, thread_enabled) def gettypedefnode(self, T, varlength=1): if 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 Sun Oct 30 01:56:16 2005 @@ -9,8 +9,9 @@ class BasicGcPolicy: - def __init__(self, db): + def __init__(self, db, thread_enabled=False): self.db = db + self.thread_enabled = thread_enabled def pyobj_incref(self, expr, T): return 'Py_XINCREF(%s);' % expr @@ -296,6 +297,12 @@ deallocator_lines = RefcountingGcPolicy.deallocator_lines.im_func + def common_after_definition(self, defnode): + if defnode.gcinfo: + gcinfo = defnode.gcinfo + if gcinfo.finalizer: + yield 'void %s(GC_PTR obj, GC_PTR ignore);' % (gcinfo.finalizer,) + # for arrays def array_setup(self, arraydefnode): @@ -313,12 +320,16 @@ yield '\t' + line yield '}' + array_after_definition = common_after_definition + # 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) + struct_after_definition = common_after_definition + def struct_implementationcode(self, structdefnode): if structdefnode.gcinfo: gcinfo = structdefnode.gcinfo @@ -360,9 +371,9 @@ return ['gc'] def pre_pre_gc_code(self): - #if sys.platform == "linux2": - # yield "#define _REENTRANT 1" - # yield "#define GC_LINUX_THREADS 1" + if sys.platform == "linux2" and self.thread_enabled: + yield "#define _REENTRANT 1" + yield "#define GC_LINUX_THREADS 1" yield '#include ' yield '#define USING_BOEHM_GC' Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Sun Oct 30 01:56:16 2005 @@ -18,9 +18,10 @@ symboltable = None stackless = False - def __init__(self, translator, gcpolicy=None, libraries=None): + def __init__(self, translator, gcpolicy=None, libraries=None, thread_enabled=False): self.translator = translator self.gcpolicy = gcpolicy + self.thread_enabled = thread_enabled if libraries is None: libraries = [] @@ -28,7 +29,8 @@ def build_database(self): translator = self.translator - db = LowLevelDatabase(translator, standalone=self.standalone, gcpolicy=self.gcpolicy) + db = LowLevelDatabase(translator, standalone=self.standalone, + gcpolicy=self.gcpolicy, thread_enabled=self.thread_enabled) if self.stackless: from pypy.translator.c.stackless import StacklessData Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Sun Oct 30 01:56:16 2005 @@ -16,6 +16,9 @@ DEFAULT_OPTIONS = optparse.Values(defaults={ 'gc': 'ref', + + 'thread': False, # influences GC policy + 'stackless': False, 'debug': True, 'insist': False, @@ -190,7 +193,9 @@ from pypy.translator.c import gc gcpolicy = gc.NoneGcPolicy - cbuilder = translator.cbuilder(standalone=standalone, gcpolicy=gcpolicy) + cbuilder = translator.cbuilder(standalone=standalone, + gcpolicy=gcpolicy, + thread_enabled = getattr(opt, 'thread', False)) cbuilder.stackless = opt.stackless database = cbuilder.build_database() self.log.info("database for generating C source was created") Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Sun Oct 30 01:56:16 2005 @@ -44,9 +44,31 @@ # _____ Define and setup target ___ +# for now this will do for option handling + +take_options = True + +def opt_parser(): + import py + defl = {'thread': False} + parser = py.compat.optparse.OptionParser(usage="target PyPy standalone", add_help_option=False) + parser.set_defaults(**defl) + parser.add_option("--thread", action="store_true", dest="thread", help="enable threading") + return parser + +def print_help(): + opt_parser().print_help() + + def target(driver, args): options = driver.options + tgt_options, _ = opt_parser().parse_args(args) + + translate_pypy.log_options(tgt_options, "target PyPy options in effect") + + options.thread = tgt_options.thread + global space, w_entry_point geninterp = not getattr(options, 'lowmem', False) @@ -58,12 +80,13 @@ # disable translation of the whole of classobjinterp.py StdObjSpace.setup_old_style_classes = lambda self: None - if options.gc == 'boehm': - #print "disabling thread with boehm for stabilitiy (combination not tested)" - #print "trying threads and boehm" - usemodules = [] - else: - usemodules = ['thread'] + + usemodules = [] + if options.thread: + print "threads unsupported right now: need thread-safe stack_too_big" + raise SystemExit + usemodules.append('thread') + space = StdObjSpace(nofaking=True, compiler="ast", # interpreter/astcompiler translating=True, 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 Sun Oct 30 01:56:16 2005 @@ -84,6 +84,8 @@ } defaults = { + 'help': False, + 'targetspec': 'targetpypystandalone', 'goals': [], @@ -139,24 +141,31 @@ def goal_cb(option, opt, value, parser, enable, goal): if enable: - if goal not in parser.values.goals: + if goal not in parser.values.ensure_value('goals', []): parser.values.goals = parser.values.goals + [goal] else: - if goal not in parser.values.skipped_goals: + if goal not in parser.values.ensure_value('skipped_goals', []): parser.values.skipped_goals = parser.values.skipped_goals + [goal] def load_target(targetspec): log.info("Translating target as defined by %s" % targetspec) if not targetspec.endswith('.py'): targetspec += '.py' - targetspec_dic = {'__name__':'__rpythonmain__'} + thismod = sys.modules[__name__] + targetspec_dic = {'__name__':'__rpythonmain__', + 'translate_pypy': thismod} sys.path.insert(0, os.path.dirname(targetspec)) execfile(targetspec, targetspec_dic) return targetspec_dic def parse_options_and_load_target(): - opt_parser = optparse.OptionParser(usage="%prog [options] [target]", prog="translate_pypy", - formatter=OptHelpFormatter()) + opt_parser = optparse.OptionParser(usage="%prog [options] [target] [target-specific-options]", + prog="translate_pypy", + formatter=OptHelpFormatter(), + add_help_option=False) + + opt_parser.disable_interspersed_args() + for group_name, grp_opts in bunchiter(opts): grp = opt_parser.add_option_group(group_name) for dest, dest_opts in bunchiter(grp_opts): @@ -183,7 +192,10 @@ grp.add_option(*names, **opt_setup) - opt_parser.set_defaults(**defaults) + # add help back as a flag + opt_parser.add_option("-h", "--help", + action="store_true", dest="help", + help="show this help message and exit") options, args = opt_parser.parse_args() @@ -195,16 +207,49 @@ "ambiguous file naming, please rename %s" % arg) options.targetspec = arg elif os.path.isfile(arg) and arg.endswith('.py'): - options.targetspec = arg[:-3] + options.targetspec = arg[:-3] + else: + args = [arg] + args + + # for help, applied later + opt_parser.set_defaults(**defaults) + + targetspec = options.ensure_value('targetspec', opt_parser.defaults['targetspec']) + targetspec_dic = load_target(targetspec) + + if args and not targetspec_dic.get('take_options', False): + log.WARNING("target specific arguments supplied but will be ignored: %s" % ' '.join(args)) - targespec_dic = load_target(options.targetspec) + # target specific defaults taking over + if 'opt_defaults' in targetspec_dic: + opt_parser.set_defaults(targetspec_dic['op_defaults']) + + if options.help: + opt_parser.print_help() + if 'print_help' in targetspec_dic: + print + targetspec_dic['print_help']() + sys.exit(0) + + # apply defaults + for name, val in opt_parser.defaults.iteritems(): + options.ensure_value(name, val) # tweak: default_goals into default_goal del options.default_goals options.default_goal = 'compile' - return targespec_dic, options, args + return targetspec_dic, options, args +def log_options(options, header="options in effect"): + # list options (xxx filter, filter for target) + log('%s:' % header) + optnames = options.__dict__.keys() + optnames.sort() + for name in optnames: + optvalue = getattr(options, name) + log('%25s: %s' %(name, optvalue)) + def main(): targetspec_dic, options, args = parse_options_and_load_target() @@ -259,14 +304,8 @@ pdb_plus_show.start(tb, server_setup, graphic=not options.text) - # list options (xxx filter, filter for target) - log('options in effect:') - optnames = options.__dict__.keys() - optnames.sort() - for name in optnames: - optvalue = getattr(options, name) - log('%25s: %s' %(name, optvalue)) - + log_options(options) + try: drv = driver.TranslationDriver.from_targetspec(targetspec_dic, options, args, empty_translator=t, Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Sun Oct 30 01:56:16 2005 @@ -303,12 +303,12 @@ cbuilder.import_module() return cbuilder.get_entry_point() - def cbuilder(self, standalone=False, gcpolicy=None): + def cbuilder(self, standalone=False, gcpolicy=None, thread_enabled=False): from pypy.translator.c import genc if standalone: - return genc.CStandaloneBuilder(self, gcpolicy=gcpolicy) + return genc.CStandaloneBuilder(self, gcpolicy=gcpolicy, thread_enabled=thread_enabled) else: - return genc.CExtModuleBuilder(self, gcpolicy=gcpolicy) + return genc.CExtModuleBuilder(self, gcpolicy=gcpolicy, thread_enabled=thread_enabled) def llvmcompile(self, really_compile=True, standalone=False, optimize=True, exe_name=None, gcpolicy=None): """llvmcompile(self, really_compile=True, standalone=False, optimize=True) -> LLVM translation From arigo at codespeak.net Sun Oct 30 10:48:26 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Oct 2005 10:48:26 +0100 (CET) Subject: [pypy-svn] r19175 - pypy/dist/pypy/doc Message-ID: <20051030094826.676DA27B7D@code1.codespeak.net> Author: arigo Date: Sun Oct 30 10:48:23 2005 New Revision: 19175 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Finished the Soundness part. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Sun Oct 30 10:48:23 2005 @@ -1491,12 +1491,13 @@ (for the given user program). If *r* is a rule, then it can be considered as a (mathematical) function from the set of states to the set of states, so that "applying" the rule means computing ``(b',E') = -r( (b,E) )``. To formalize the meta-rule describing rescheduling of -rules, we introduce a third component in the state: a subset *S* of the -*Rules* which stands for the currently scheduled rules. Finally, for -any variable *v* we write *Rules_v* for the set of rules that have *v* -as an input or auxiliary variable. The rule titled ``(x~y) in E`` is -called *r_x~y* for short, and it belongs to *Rules_x* and *Rules_y*. +r( (b,E) )``. If the guards of the rule *r* are not satisfied then ``r( +(b,E) ) = (b,E)``. To formalize the meta-rule describing rescheduling +of rules, we introduce a third component in the state: a subset *S* of +the *Rules* which stands for the currently scheduled rules. Finally, +for any variable *v* we write *Rules_v* for the set of rules that have +*v* as an input or auxiliary variable. The rule titled ``(x~y) in E`` +is called *r_x~y* for short, and it belongs to *Rules_x* and *Rules_y*. The meta-rule can be formalized as follows: we start from the initial "meta-state" *(S_0, b_0, E_0)*, where *S_0=Rules* and *(b_0, E_0)* is @@ -1615,21 +1616,51 @@ consider separate cases for each of the kind of rules that *r_i* can be. We only show a few representative examples and leave the complete proof to the reader. These example show why it is a key - point that *(bs,Es)* is not degenerated. + point that *(bs,Es)* is not degenerated: most rules no longer + apply if an annotation degenerates to ``Top``, but continue to + apply if it is generalized to anything below ``Top``. The + general idea is to turn each rule into a step of the complete + proof, showing that if a sound state is at least as general as + ``(b_i, E_i)`` then it must be at least as general as ``(b_i+1, + E_i+1)``. Example 1. The rule *r_i* is:: - z=add(x,y), b(x)=Int, Bool<=b(y)<=Int + z=add(x,y), b(x)=Int, Bool<=b(y)<=Int + ------------------------------------------------------ + b' = b with (z->Int) + + In this example, assuming that the guards are satisfied, *b_i+1* + is *b_i* with ``z->Int``. We must show that ``bs(z) >= Int``. + We know from ``(b_i, E_i) <= (bs,Es)`` that ``bs(x) >= Int`` and + ``bs(y) >= Bool``. As *bs* is not degenerated, we have more + precisely ``bs(x) = Int, Bool <= bs(y) <= Int``. Moreover, by + definition ``r( (bs,Es) ) = (bs,Es)``. We conclude that ``bs(z) + = Int``. + + Example 2. The rule *r_i* is:: + + y = phi(x) + ---------------------------------------- + merge b(x) => y + + We must show that ``bs(y) >= b_i+1(y)``. We need to subdivide + this example in two cases: either ``b(x)`` and ``b(y)`` are both + ``List`` annotations or not. + + If they are not, we know that ``b_i+1(y) = b_i(y) \/ b_i(x)`` and + ``bs(y) >= b_i(y)``, so that we must show that ``bs(y) >= + b_i(x)``. We know that ``r( (bs,Es) ) = (bs,Es)`` so that + ``bs(y) = bs(x) \/ bs(y)``, i.e. ``bs(y) >= bs(x)``. We conclude + by noting that ``bs(x) >= b_i(x)``. + + On the other hand, if ``b(x) = List(v)`` and ``b(y) = List(w)``, + then *b_i+1* is *b_i* but *E_i+1* is *E_i* with ``v~w``. We must + show that ``(v~w) in Es``. As *(bs,Es)* is at least as general + as *(b_i, E_i)* but not degenerated we know that ``bs(x) = + List(v)`` and ``bs(y) = List(w)`` as well. Again, because ``r( + (bs,Es) ) = (bs,Es)`` we conclude that ``(v~w) in Es``. - In this example, *b_i+1* is *b_i* with ``z->Int``. We must show - that ``bs(z) >= Int``. To do so, consider that for - non-degenerated states the guards of the above rule are - equivalent to ``b(x)>=Int, b(y)>=Bool``. As *z* is not the same - variable as *x* or *y*, we know from ``(b_i, E_i) <= (bs,Es)`` - that ``bs(x)>=Int`` and ``bs(y)>=Bool``. Moreover, by definition - ``r( (bs,Es) ) = (bs,Es)``. We conclude that ``bs(z)=Int``. - - XXX Complexity From arigo at codespeak.net Sun Oct 30 11:02:37 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Oct 2005 11:02:37 +0100 (CET) Subject: [pypy-svn] r19176 - pypy/dist/pypy/doc Message-ID: <20051030100237.0BF0E27B84@code1.codespeak.net> Author: arigo Date: Sun Oct 30 11:02:34 2005 New Revision: 19176 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Hand-waving about complexity. Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Sun Oct 30 11:02:34 2005 @@ -1662,7 +1662,6 @@ (bs,Es) ) = (bs,Es)`` we conclude that ``(v~w) in Es``. - Complexity ********** @@ -1680,8 +1679,23 @@ to prove that there is no infinite ascending chain, which is enough to guarantee termination. -Additionally, an important property of ``lookup_filter`` is to be -monotonic: XXX +We will not present a formal bound on the complexity of the algorithm. +Worst-case senarios would expose severe theoretical problems. In +practice, these senarios are unlikely. Empirically, when annotating a +large program like PyPy consisting of some 20'000 basic blocks from +4'000 functions, the whole annotation process finishes in 5 minutes on a +modern computer. This suggests that our approach scales quite well. We +also measured how many times each rule is re-applied; the results change +from run to run due to the non-deterministic nature of the meta-rule -- +we pick a random next rule to apply at each step -- but seems to be +consistently between 20 and 40, which suggests an ``n log(n)`` practical +complexity. + +Moreover, we will have to explore modular annotation in the near future +for other reasons -- to make the compiled PyPy interpreter modular, +which is an important strength of CPython. We plan to do this by +imposing the annotations at selected interface boundaries and annotating +each part independently. Non-static aspects From arigo at codespeak.net Sun Oct 30 11:22:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Oct 2005 11:22:27 +0100 (CET) Subject: [pypy-svn] r19177 - pypy/dist/pypy/doc Message-ID: <20051030102227.479BC27B6E@code1.codespeak.net> Author: arigo Date: Sun Oct 30 11:22:25 2005 New Revision: 19177 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: Completing specialization Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Sun Oct 30 11:22:25 2005 @@ -1363,7 +1363,7 @@ As we have seen in `Classes and instances`_ above, the initial binding of ``v_C.attr`` is regular and downwards-closed by construction. Moreover, the ``setattr`` - rule explicitely checks that it is never adding any potential + rule explicitly checks that it is never adding any potential bound method object to ``b(v_C.attr)``, so that the only way such objects can be added to ``b(v_C.attr)`` is via the identification of ``v_C.attr`` with other ``v_B.attr`` @@ -1701,6 +1701,14 @@ Non-static aspects ~~~~~~~~~~~~~~~~~~ +In practice, the annotation is much less "static" than the theoretical +model presented above. All functions and classes are discovered while +annotating, not in advance. In addition, as explained above, annotation +occasionally reverts to concrete mode execution to force lazy objects to +be computed or to fill more caches. We describe below some of these +aspects. + + Specialization *************** @@ -1715,17 +1723,35 @@ The fact that we allow unrestricted dynamism at bootstrap helps a great deal, but in addition we also support the explicit flagging of certain functions or classes as requiring special treatment. One such -special treatment is support for parametric polymorphism, which if -supported for all callables would lead to an explosion of function +special treatment is support for parametric polymorphism. If this were +supported for all callables, it would lead to an explosion of function implementations and likely the need for some kind of target specific -type erasure and coalescing. +type erasure and coalescing. Instead, the user-provided flag instructs +the annotator to only create a new copy of a few specific functions for +each annotation seen for a specific argument. + +Another special treatment is more outright special casing +(black-boxing): the user can provide code to explicitly compute the +annotation information for a given function, without letting the flow +object space and annotator abstractly interpret the function's bytecode. + +In more details, the following special-cases are supported by default +(more advanced specializations have been implemented specifically for +PyPy): + +* specializing a function by the annotation of a given argument + +* specializing a function by the value of a given argument (requires all + calls to the function to resolve the argument to a constant value) + +* ignoring -- the function call is ignored. Useful for writing tests or + debugging support code that should be removed during translation. + +* ``*args`` XXX -Another special treatment is more outright special casing: providing -code to explicitly compute the annotation information for a given -function as opposed to abstractly interpreting the function's -bytecode. +* memo XXX -XXX details of what is supported +* ctr_location XXX From arigo at codespeak.net Sun Oct 30 17:52:46 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Oct 2005 17:52:46 +0100 (CET) Subject: [pypy-svn] r19189 - pypy/dist/pypy/doc Message-ID: <20051030165246.28FE227B6E@code1.codespeak.net> Author: arigo Date: Sun Oct 30 17:52:43 2005 New Revision: 19189 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: * Specialization (finished) * Concrete mode execution * Constant propagation * Termination with non-static aspects Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Sun Oct 30 17:52:43 2005 @@ -1747,19 +1747,101 @@ * ignoring -- the function call is ignored. Useful for writing tests or debugging support code that should be removed during translation. -* ``*args`` XXX - -* memo XXX - -* ctr_location XXX - - - -XXX executing more user program code (idem) - -XXX constant propagation to remove bootstrap-only code - -XXX termination even with non-static aspects +* by arity -- for functions taking a variable number of (non-keyword) + arguments via a ``*args``, the default specialization is by the number + of extra arguments. (This follows naturally from the fact that the + extended annotation lattice we use has annotations of the form + ``Tuple(A_1, ..., A_n)`` representing a heterogenous tuple of length + *n* whose items are respectively annotated with ``A_1, ..., A_n``, but + there is no annotation for tuples of unknown length.) + +* ctr_location -- for classes. A fresh independent copy of the class is + made for each program point that instantiate the class. This is a + simple (but potentially overspecializing) way to obtain class + polymorphism for the couple of container classes we needed in PyPy + (e.g. Stack). + +* memo -- the calls to such functions are fully computed at annotation + time. This requires that each call site finds each argument to be + either constant or element of a finite set (``Pbc(m)`` or ``Bool``). + All possible call patterns are tried at annotation time, and the + return annotation is the union of all possible results. Such + functions are then compiled as memo table lookups -- their + implementation is neither analysed nor translated. + + +Concrete mode execution +*********************** + +The *memo* specialization_ is used at key points in PyPy to obtain the +effect described in the introduction (see `Abstract interpretation`_): +the memo functions and all the code it invokes is concretely executed +during annotation. There is no staticness restriction on that code -- +it will typically instantiate classes, creating more prebuilt instances, +and sometimes even build new classes and functions; this possibility is +used quite extensively in PyPy. + +The input arguments to a memo function are not known in advance: they +are discovered by the annotator, typically as a ``Pbc(m)`` annotation +where the set *m* grows over time when rules are re-applied. In this +sense, switching to concrete mode execution is an integral part of our +annotation process. + + +Constant propagation +******************** + +The extended lattice of annotations used in practice differs from the +one presented above in that almost any annotation can also optionally +carry a constant value. For example, there are annotations like +``NonNegInt(const=42)`` for all integers; these annotations are between +``Bottom`` and ``NonNegInt``. The annotator carries the constant tag +across simple operations whenever possible. The main effect we are +researching here is not merely constant propagation (low-level compilers +are very good at this already), but dead code removal. Indeed, when a +branch condition is ``Bool(const=True)`` or ``Bool(const=False)``, then +the annotator will only follow one of the branches -- or in the above +formalism: the ``y=phi(x)`` rules that propagate annotations across +links between basic blocks are guarded by the condition that the switch +variable carries an annotation of either ``Bool(const=)`` or +``Bool``. + +The dead code removal effect is used in an essential way to hide +bootstrap-only code from the annotator where it could not analyse such +code. For example, some frozen prebuilt constants force some of their +caches to be filled when they are frozen (which occurs the first time +the annotator discovers such a constant). This allows the regular +access methods of the frozen prebuilt constant to contain code like:: + + if self.not_computed_yet: + self.compute_result() + return self.result + +As the annotator only sees frozen ``self`` constants with +``not_computed_yet=False``, it annotates this attribute as +``Bool(const=False)`` and never follows the call to +``compute_result()``. + + +Termination with non-static aspects +*********************************** + +The non-static aspects, and concrete mode execution more particularly, +makes it impossible to prove that annotation terminates in general. It +could be the case that a memo function builds and returns a new class +for each class that it receives as argument, and the result of this memo +function could be fed back to its input. However, what can be proved is +that annotation terminates under some conditions on the user program. A +typical sufficient condition (which is true for PyPy) is that there must +be a computable bound on the number of functions and classes that can +ever exist in the user program at run-time. + +For annotation to terminate -- and anyway for translation to a low-level +language like C to have any chance of being reasonably straightforward +to do -- it is up to the user program to satisfy such a condition. (It +is similar to, but more "global" than, the flow object space's +restriction to terminate only if fed functions that don't obviously go +into infinite loops.) Code Generation From arigo at codespeak.net Sun Oct 30 18:41:01 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Oct 2005 18:41:01 +0100 (CET) Subject: [pypy-svn] r19190 - pypy/dist/pypy/doc Message-ID: <20051030174101.7B09827B7D@code1.codespeak.net> Author: arigo Date: Sun Oct 30 18:40:59 2005 New Revision: 19190 Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Log: "Finished" this with an abruptly short final chapter for RTyping+GenC. Do we really want this at all? Or should it be longer? Modified: pypy/dist/pypy/doc/draft-dynamic-language-translation.txt ============================================================================== --- pypy/dist/pypy/doc/draft-dynamic-language-translation.txt (original) +++ pypy/dist/pypy/doc/draft-dynamic-language-translation.txt Sun Oct 30 18:40:59 2005 @@ -1847,29 +1847,109 @@ Code Generation =============================== -XXX rewriting to low-level operations +The actual generation of low-level code from the information computed by +the annotator is not the central subject of the present report, so we +will only skim it and refer to the reference documentation when +appropriate. + +The main difficulty with turning annotated flow graphs into C code is +that the RPython definition is still quite large, in the sense that an +important fraction of the built-in data structures of Python, and the +methods on them, are supported -- sometimes requiring highly non-trivial +implementations, in a polymorphic way. Various approaches have been +tried out, including writing a lot of template C code that gets filled +with concrete types. + +The approach eventually selected is different. We proceed in two steps: + +* the annotated graphs are rewritten so that each RPython-level + operation is replaced by one or a few low-level operations (or a call + to a helper for more complex operations); -XXX introduction, repr +* the low-level flow graphs thus obtained are easy to handle in a + back-end -- we can currently turn them into either C or LLVM_ code. -Low-level type system for C -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -XXX +The RPython typer +~~~~~~~~~~~~~~~~~ -Implementing operations as helpers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The first step is called "RTyping" or "specializing" as it turns general +high-level operations into low-level C-like operations specialized for +the types derived by the annotator. This process produces a globally +consistant low-level family of flow graphs by assuming that the +annotation state is sound. It is described in more details in the +`RPython typer`_ reference. + +A noteworthy point of the RTyper is that for each operation that has no +obvious C-level equivalent, we write a helper function in Python; each +usage of the operation in the source (high-level) annotated flow graph +is replaced by a call to this function. The function in question is +implemented in terms of "simpler" operations. The function is then fed +back into the flow object space and the annotator and the RTyper itself +so that it gets turned into another low-level control flow graph. At +this point, the annotator runs with a different set of default +specializations: it allows several copies of the helper functions to be +automatically built, one for each low-level type of its arguments. We +do this by default at this level because of the intended purpose of +these helpers: they are usually methods of a polymorphic container. + +This approach shows that our annotator is versatile enough to accomodate +different kinds of sub-languages at different levels: it is +straightforward to adapt it for the so-called "low-level Python" +language in which we constrain ourselves to write the low-level +operation helpers. Automatic specialization was a key point here; the +resulting language feels like a basic C++ without any type or template +declarations. -XXX XXX reusing the annotator and specialization Generating C code ~~~~~~~~~~~~~~~~~ -XXX collecting functions and data structures recursively +So far, all data structures (flow graphs, prebuilt constants...) +manipulated by the translation process only existed as objects in +memory. The last step is to turn them into an external representation +like C source code. + +This step is theoretically straightforward, if messy in practice for +various reasons including the limitations, constrains and irregularities +of the C language. + +The `GenC back-end`_ works again in two steps: + +* it first collects recursively all functions (i.e. their low-level flow + graphs) and all prebuilt data structures, remembering all "struct" C + types that will need to be declared; + +* it then generates one or multiple C source files containing: + + 1. a forward declaration of all the "struct" C types; + + 2. the full declarations of the latter; + + 3. a forward declaration of all the functions and prebuilt data + structures; + + 4. the implementation of the latter (i.e. the body of functions and + the static initializers of prebuilt data structures). + +Each function's body is implemented as basic blocks (following the basic +blocks of the control flow graphs) with jumps between them. The +low-level operations that appear in the low-level flow graphs are each +turned into a simple C operation. A few functions have no flow graph +attached to them: the "primitive" functions. No body is written for +them; GenC assumes that a manually-written implementation will be +provided in another C file. + + +Conclusion +=============== -XXX inserting hand-written C functions for suggested_primitives +XXX looks like a general approach for dynamic language translation -XXX messy +XXX static analysis is delicate; dynamic analysis interesting potential +XXX tests are good, otherwise translating the whole of PyPy would have +been a nightmare .. _architecture: architecture.html @@ -1882,5 +1962,8 @@ .. _`Standard Object Space`: objspace.html#the-standard-object-space .. _`ACM SIGPLAN 2004 paper`: http://psyco.sourceforge.net/psyco-pepm-a.ps.gz .. _`Hindley-Milner`: http://en.wikipedia.org/wiki/Hindley-Milner_type_inference +.. _LLVM: http://llvm.cs.uiuc.edu/ +.. _`RPython typer`: translation.html#rpython-typer +.. _`GenC back-end`: translation.html#genc .. include:: _ref.txt From arigo at codespeak.net Sun Oct 30 18:52:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Sun, 30 Oct 2005 18:52:23 +0100 (CET) Subject: [pypy-svn] r19191 - pypy/dist/pypy/doc Message-ID: <20051030175223.62C0827B8A@code1.codespeak.net> Author: arigo Date: Sun Oct 30 18:52:21 2005 New Revision: 19191 Modified: pypy/dist/pypy/doc/translation.txt Log: * fix a link * add a link to draft-dynamic-language-translation, where there is at least a few paragraphs about what GenC does Modified: pypy/dist/pypy/doc/translation.txt ============================================================================== --- pypy/dist/pypy/doc/translation.txt (original) +++ pypy/dist/pypy/doc/translation.txt Sun Oct 30 18:52:21 2005 @@ -987,9 +987,11 @@ 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`_. +GenC is not really documented at the moment. The basic principle of +creating code from flowgraphs is similar to the `Python back-end`_. +See also `Generating C code`_ in another draft. +.. _`Generating C code`: draft-dynamic-language-translation.html#generating-c-code .. _LLVM: @@ -1020,12 +1022,13 @@ 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 + +.. _`Python again`: +.. _`Python back-end`: + The Interplevel Back-End ======================== From pedronis at codespeak.net Sun Oct 30 22:27:24 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 30 Oct 2005 22:27:24 +0100 (CET) Subject: [pypy-svn] r19210 - pypy/dist/pypy/translator/goal Message-ID: <20051030212724.5CA0827BA1@code1.codespeak.net> Author: pedronis Date: Sun Oct 30 22:27:23 2005 New Revision: 19210 Removed: pypy/dist/pypy/translator/goal/targetastbuilder.py pypy/dist/pypy/translator/goal/targetcompiler.py pypy/dist/pypy/translator/goal/targetparser.py Log: remove obsolete targets From pedronis at codespeak.net Sun Oct 30 22:30:47 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 30 Oct 2005 22:30:47 +0100 (CET) Subject: [pypy-svn] r19211 - pypy/release/0.8.x/pypy/translator/goal Message-ID: <20051030213047.DFB1627BAA@code1.codespeak.net> Author: pedronis Date: Sun Oct 30 22:30:46 2005 New Revision: 19211 Removed: pypy/release/0.8.x/pypy/translator/goal/targetastbuilder.py pypy/release/0.8.x/pypy/translator/goal/targetcompiler.py pypy/release/0.8.x/pypy/translator/goal/targetparser.py Log: merge rev 19210, remove obsolote targets From pedronis at codespeak.net Sun Oct 30 22:36:15 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 30 Oct 2005 22:36:15 +0100 (CET) Subject: [pypy-svn] r19212 - pypy/dist/pypy/translator/goal Message-ID: <20051030213615.8568427BAA@code1.codespeak.net> Author: pedronis Date: Sun Oct 30 22:36:14 2005 New Revision: 19212 Modified: pypy/dist/pypy/translator/goal/targetthunkstandalone.py Log: disable broken threads here too. Modified: pypy/dist/pypy/translator/goal/targetthunkstandalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetthunkstandalone.py (original) +++ pypy/dist/pypy/translator/goal/targetthunkstandalone.py Sun Oct 30 22:36:14 2005 @@ -58,12 +58,15 @@ # disable translation of the whole of classobjinterp.py Space.setup_old_style_classes = lambda self: None - if options.gc == 'boehm': - #print "disabling thread with boehm for stabilitiy (combination not tested)" - #print "trying threads and boehm" - usemodules = [] - else: - usemodules = ['thread'] + # XXX threads are not working right now! + #if options.gc == 'boehm': + # #print "disabling thread with boehm for stabilitiy (combination not tested)" + # #print "trying threads and boehm" + # usemodules = [] + #else: + # usemodules = ['thread'] + usemodules = [] + space = Space(nofaking=True, compiler="ast", # interpreter/astcompiler translating=True, From hpk at codespeak.net Sun Oct 30 22:40:13 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 30 Oct 2005 22:40:13 +0100 (CET) Subject: [pypy-svn] r19213 - pypy/extradoc/talk/pycon2006 Message-ID: <20051030214013.47F6627BB0@code1.codespeak.net> Author: hpk Date: Sun Oct 30 22:40:10 2005 New Revision: 19213 Added: pypy/extradoc/talk/pycon2006/opensource-business.txt - copied, changed from r19127, pypy/extradoc/talk/pycon2006/draft-soft.txt Removed: pypy/extradoc/talk/pycon2006/draft-soft.txt Log: rename open-source proposal and refine it / reformat to accomodate pycon guidelines (instead of CCC) From hpk at codespeak.net Sun Oct 30 22:40:46 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Sun, 30 Oct 2005 22:40:46 +0100 (CET) Subject: [pypy-svn] r19214 - pypy/extradoc/talk/pycon2006 Message-ID: <20051030214046.3D9A127BB5@code1.codespeak.net> Author: hpk Date: Sun Oct 30 22:40:43 2005 New Revision: 19214 Modified: pypy/extradoc/talk/pycon2006/pylib.txt pypy/extradoc/talk/pycon2006/pypy-archsession.txt Log: small refinements to pylib and pypy-archsession talk we should submit the lot some time monday ... Modified: pypy/extradoc/talk/pycon2006/pylib.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pylib.txt (original) +++ pypy/extradoc/talk/pycon2006/pylib.txt Sun Oct 30 22:40:43 2005 @@ -7,7 +7,9 @@ ------------------- holger krekel +Armin Rigo py-dev at codespeak.net (py lib developers list) +http://codespeak.net/py/ (web page) Requested Timeslot ------------------ @@ -21,7 +23,7 @@ Already known for the widely used py.test tool, the "py lib" has more to offer. We are going to explore the -experimental package "name export mechanism" which involves +experimental package "name export mechanism" also involving lazy imports, a lightweight tag/keyword-based logging scheme, subversion and local Path objects and compatibility modules that make recent Python library modules uniformly available from older @@ -29,22 +31,20 @@ "py.execnet" which explores new interprocess-communication facilities. All of these features are already used by a growing number of projects. We will give interactive examples and -conclude with an overview of what comes next. +conclude with an outlook. Presentation Outline -------------------- -The py lib is a development support library -and evolves from a strictly test-driven process. -Apart from its intense usage in the PyPy project -a number of other projects have adapted its methods. -We plan to give usage examples for various parts -of the py library. The current key parts of the py lib -we will present are: - -- py.log: keyword & subscription based lazy logging -- py.compat: use newer standard library modules from older - python versions +The py lib is a development support library and evolves itself +from a strictly test-driven development process. Apart from +its intense usage in the PyPy project a number of other +projects have adapted its methods. We plan to give usage +examples for various parts of the py library. The current key +parts of the py lib we will present are: + +- py.log: keyword/subscription based lazy logging +- py.compat: provides standard library modules for older python versions - py.initpkg: export name/lazy import mechanism ("import py" is all you ever need to do). - py.path.*: path objects unifying access to svn- and @@ -52,11 +52,12 @@ - py.execnet: ad-hoc distributing programs across ssh- and process barriers. -We'll conclude with the next challenges for py lib development: +We'll conclude with some of the next challenges for py lib +development: - extending py.execnet to use it for peer-to-peer situations - extending/refactoring py.path to support in-memory - and other filesystems + and in general more filesystems - integrating twisted testing functionality into py.test - a release plan Modified: pypy/extradoc/talk/pycon2006/pypy-archsession.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pypy-archsession.txt (original) +++ pypy/extradoc/talk/pycon2006/pypy-archsession.txt Sun Oct 30 22:40:43 2005 @@ -23,7 +23,7 @@ (starting autumn 2005) heading towards building a specializing JIT-compiler, stackless features and translation to higher level languages into the code base. In this session we will -present and interactively discuss with the audience basic +present and interactively discuss with the audience the basic architectural pictures. We'd are going to emphasize the various emerging possibilities for further development part of which will be an ongoing effort of the European Union's funded From bea at codespeak.net Sun Oct 30 22:48:35 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sun, 30 Oct 2005 22:48:35 +0100 (CET) Subject: [pypy-svn] r19215 - pypy/extradoc/talk/pycon2006 Message-ID: <20051030214835.BE72427BBA@code1.codespeak.net> Author: bea Date: Sun Oct 30 22:48:34 2005 New Revision: 19215 Modified: pypy/extradoc/talk/pycon2006/opensource-business.txt Log: changed email. A question: "and tell you what we know of how other projects are doing it." - what projects are we going to mention here? Modified: pypy/extradoc/talk/pycon2006/opensource-business.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/opensource-business.txt (original) +++ pypy/extradoc/talk/pycon2006/opensource-business.txt Sun Oct 30 22:48:34 2005 @@ -14,7 +14,7 @@ Contact Information ------------------- -Beatrice During +Beatrice During Holger Krekel Requested Timeslot From bea at codespeak.net Sun Oct 30 23:23:33 2005 From: bea at codespeak.net (bea at codespeak.net) Date: Sun, 30 Oct 2005 23:23:33 +0100 (CET) Subject: [pypy-svn] r19216 - pypy/extradoc/talk/pycon2006 Message-ID: <20051030222333.468B327BCE@code1.codespeak.net> Author: bea Date: Sun Oct 30 23:23:32 2005 New Revision: 19216 Modified: pypy/extradoc/talk/pycon2006/opensource-business.txt Log: last change from my side - I think we are ready to go.... I will submit tomorrow after lunch (around 14:00)... Modified: pypy/extradoc/talk/pycon2006/opensource-business.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/opensource-business.txt (original) +++ pypy/extradoc/talk/pycon2006/opensource-business.txt Sun Oct 30 23:23:32 2005 @@ -46,8 +46,8 @@ We will relate the various agile techniques used in PyPy and other projects/companies to the agile practices known from -the work in the Agile Alliance (XP, Scrum, Crystal) and tell -you what we know of how other projects are doing it. +the work in the Agile Alliance (XP, Scrum, Crystal) in order to show how +agile techniques have been adopted and evolved by the Python community. Lastly we will also share our experience of various challenges and possibilities when integrating the different cultures and skills from From pedronis at codespeak.net Sun Oct 30 23:23:34 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Sun, 30 Oct 2005 23:23:34 +0100 (CET) Subject: [pypy-svn] r19217 - pypy/release/0.8.x/pypy/doc Message-ID: <20051030222334.2109827BCD@code1.codespeak.net> Author: pedronis Date: Sun Oct 30 23:23:33 2005 New Revision: 19217 Removed: pypy/release/0.8.x/pypy/doc/getting-started.txt Log: getting-started-0.8 should be document updated, then renamed, and then copied back to the trunk From hpk at codespeak.net Mon Oct 31 13:40:26 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 31 Oct 2005 13:40:26 +0100 (CET) Subject: [pypy-svn] r19227 - pypy/extradoc/talk/pycon2006 Message-ID: <20051031124026.A751E27B62@code1.codespeak.net> Author: hpk Date: Mon Oct 31 13:40:24 2005 New Revision: 19227 Modified: pypy/extradoc/talk/pycon2006/pylib.txt Log: slightly restructured the pylib proposal and submitted it to Pycon 2006. note that the pycon submission structure does not match the structure we used in svn. should have checked that earlier myself i guess ... basically one needs a summary with 250-1000 words and a presentation outline really is supposed to be the full presentation. Modified: pypy/extradoc/talk/pycon2006/pylib.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pylib.txt (original) +++ pypy/extradoc/talk/pycon2006/pylib.txt Mon Oct 31 13:40:24 2005 @@ -21,45 +21,30 @@ Title: using the py library (apart from py.test) -Already known for the widely used py.test tool, the -"py lib" has more to offer. We are going to explore the -experimental package "name export mechanism" also involving -lazy imports, a lightweight tag/keyword-based logging scheme, -subversion and local Path objects and compatibility modules that -make recent Python library modules uniformly available from older -Python versions. We also will glance into the current state of -"py.execnet" which explores new interprocess-communication -facilities. All of these features are already used by a growing -number of projects. We will give interactive examples and -conclude with an outlook. - -Presentation Outline --------------------- - The py lib is a development support library and evolves itself -from a strictly test-driven development process. Apart from -its intense usage in the PyPy project a number of other -projects have adapted its methods. We plan to give usage -examples for various parts of the py library. The current key -parts of the py lib we will present are: +from a strictly test-driven development process. Already +known for the widely used py.test tool, the "py lib" has more +to offer. + +Apart from its intense usage in the PyPy project a number of +other projects have adapted its methods. We plan to give +usage examples for various parts of the py library: -- py.log: keyword/subscription based lazy logging -- py.compat: provides standard library modules for older python versions +- py.log: keyword/subscription based lazy logging +- py.compat: provides standard library modules for older python versions - py.initpkg: export name/lazy import mechanism ("import py" is all you ever need to do). -- py.path.*: path objects unifying access to svn- and - local filesystems. +- py.path: path objects unifying access to svn- and + local filesystems. - py.execnet: ad-hoc distributing programs across ssh- and process barriers. -We'll conclude with some of the next challenges for py lib -development: +All of these features are already used by a growing number of +projects. We will give interactive examples and conclude +with an outlook. -- extending py.execnet to use it for peer-to-peer situations -- extending/refactoring py.path to support in-memory - and in general more filesystems -- integrating twisted testing functionality into py.test -- a release plan +Presentation Outline (optional) +--------------------------------- Intended audience ----------------- From hpk at codespeak.net Mon Oct 31 13:42:57 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 31 Oct 2005 13:42:57 +0100 (CET) Subject: [pypy-svn] r19228 - pypy/extradoc/talk/pycon2006 Message-ID: <20051031124257.39BA327B6A@code1.codespeak.net> Author: hpk Date: Mon Oct 31 13:42:55 2005 New Revision: 19228 Modified: pypy/extradoc/talk/pycon2006/pypy-archsession.txt Log: adapted pypy-archsession to pycon structure (only a big summary basically) Modified: pypy/extradoc/talk/pycon2006/pypy-archsession.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pypy-archsession.txt (original) +++ pypy/extradoc/talk/pycon2006/pypy-archsession.txt Mon Oct 31 13:42:55 2005 @@ -29,11 +29,8 @@ which will be an ongoing effort of the European Union's funded part of the PyPy project. -Presentation Outline --------------------- - -We'll describe architectural pictures and point -out extension and optimization possibilities: +In particular, we'll describe the following architectural pictures +and point out extension and optimization possibilities: - Language Implementation: Bytecode Interpreter and Object Space interaction - Translation to low level languages (C/LLVM) From hpk at codespeak.net Mon Oct 31 13:44:59 2005 From: hpk at codespeak.net (hpk at codespeak.net) Date: Mon, 31 Oct 2005 13:44:59 +0100 (CET) Subject: [pypy-svn] r19229 - pypy/extradoc/talk/pycon2006 Message-ID: <20051031124459.2D49A27B6A@code1.codespeak.net> Author: hpk Date: Mon Oct 31 13:44:57 2005 New Revision: 19229 Modified: pypy/extradoc/talk/pycon2006/opensource-business.txt Log: dumbly doing the merge for Bea's talk as well (Bea: you need to go to http://submit.python.org and register yourself and then submit the proposal) And they don't have co-talkers usually so we just need to insert names in front of the summary text or so. Modified: pypy/extradoc/talk/pycon2006/opensource-business.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/opensource-business.txt (original) +++ pypy/extradoc/talk/pycon2006/opensource-business.txt Mon Oct 31 13:44:57 2005 @@ -31,9 +31,6 @@ project which has a 7 company/university consortium and a 1.3 Million Euro research grant from the European Union. -Presentation outline --------------------- - We'd like to present and discuss models and experiences for connecting open-source/hacking culture driven development to money related projects and goals with the audience. From tismer at codespeak.net Mon Oct 31 15:48:14 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 15:48:14 +0100 (CET) Subject: [pypy-svn] r19235 - pypy/dist/pypy/rpython Message-ID: <20051031144814.740E727B62@code1.codespeak.net> Author: tismer Date: Mon Oct 31 15:48:12 2005 New Revision: 19235 Modified: pypy/dist/pypy/rpython/rstack.py (props changed) pypy/dist/pypy/rpython/rtyper.py Log: fixeol plus a typo Modified: pypy/dist/pypy/rpython/rtyper.py ============================================================================== --- pypy/dist/pypy/rpython/rtyper.py (original) +++ pypy/dist/pypy/rpython/rtyper.py Mon Oct 31 15:48:12 2005 @@ -739,7 +739,7 @@ raise TyperError("don't know how to convert from %r to %r" % (r_from, r_to)) if v.concretetype != r_to.lowleveltype: - raise TyperError("bug in convertion from %r to %r: " + raise TyperError("bug in conversion from %r to %r: " "returned a %r" % (r_from, r_to, v.concretetype)) return v From tismer at codespeak.net Mon Oct 31 15:49:35 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 15:49:35 +0100 (CET) Subject: [pypy-svn] r19236 - pypy/dist/pypy/translator/locality Message-ID: <20051031144935.AC0C927B62@code1.codespeak.net> Author: tismer Date: Mon Oct 31 15:49:34 2005 New Revision: 19236 Modified: pypy/dist/pypy/translator/locality/calltree.py pypy/dist/pypy/translator/locality/projection.py pypy/dist/pypy/translator/locality/simulation.py Log: stopping this locality thing for a while, after it turned out that the problem is not about the physical distance of code, but we need to use coloring of cache lines, instead. Modified: pypy/dist/pypy/translator/locality/calltree.py ============================================================================== --- pypy/dist/pypy/translator/locality/calltree.py (original) +++ pypy/dist/pypy/translator/locality/calltree.py Mon Oct 31 15:49:34 2005 @@ -86,10 +86,29 @@ return res def simulate(self): - log.calltree('building CallTree...') + log.simulate('building SimGraph for simulation...') sim = SimGraph(self.nodes, FlowSimNode, self.calls) - log.calltree('simulating...') - sim.sim_all(0.9, 50) - # here I'm still playing around with parameters. - import pdb - pdb.set_trace() + log.simulate('simulating...') + sim.sim_all(1.9, 50) + self.statgraph = sim + + def optimize(self): + log.topology('building SpaceGraph for topological sort...') + sg = SpaceGraph(self.statgraph) + steps = 500 + try: + for i in range(steps): + for k in range(10): + sg.do_correction() + sg.normalize() + s = "step %d of %d lonelyness = %g" % (i+1, steps, sg.lonelyness()) + log.topology(s) + except KeyboardInterrupt: + log.topology("aborted after %d steps" % (i+1)) + self.topology = sg + log.topology("done.") + + def ordered_funcnodes(self): + nodes = self.topology.order() + ret = [node.func for node in nodes] + return ret Modified: pypy/dist/pypy/translator/locality/projection.py ============================================================================== --- pypy/dist/pypy/translator/locality/projection.py (original) +++ pypy/dist/pypy/translator/locality/projection.py Mon Oct 31 15:49:34 2005 @@ -138,16 +138,12 @@ return Vector(lonely).norm2() def forcevector(self): - # weighted implementation of the "rubber2" algorithm, - # from "PolyTop", (C) Christian Tismer / Gerhard G. Thomas 1992 vec = Vector() + k = sum(self.weights) for w, rel in zip(self.weights, self.relations): tmp = rel.position - self.position - lng = tmp.norm2() - tmp *= w * lng + tmp *= w vec += tmp - # this is a little faster than - # vec += (rel.position - self.position) * w * self.distance(rel) return vec @@ -203,6 +199,11 @@ todo.append(rel) self.subgraphs.append(todo) + def order_subgraphs(self): + sgs = [ (-len(sg), sg[0].name, sg) for sg in self.subgraphs] + sgs.sort() + self.subgraphs = [sg for lng, name, sg in sgs] + def normalize(self): # identify disjoint subgraphs. # for every subgraph: @@ -211,6 +212,7 @@ # shift all graphs to be in disjoint intervals on the x-axis. if not self.subgraphs: self.compute_subgraphs() + self.order_subgraphs() def distort(nodes): # stretch collapsed x-axis for i, node in enumerate(nodes): @@ -221,8 +223,11 @@ xmin, xmax = self.xminmax(nodes) xwidth = xmax - xmin if not xwidth: # degenerated - return norm_subgraph(distort(nodes)) - factor = (len(nodes) - 1) / xwidth + if len(nodes) > 1: + return norm_subgraph(distort(nodes), start) + factor = 1.0 + else: + factor = (len(nodes) - 1) / xwidth mean = Vector() for node in nodes: mean += node.position @@ -244,16 +249,10 @@ start += len(nodes) self.lastdim = dim - def do_correction(self, korr=0.13): + def do_correction(self, korr=0.0002): forcevecs = [node.forcevector() for node in self.nodes] - corrx = [vec[0] for vec in forcevecs] - maxcorr = abs(max(corrx)) - xmin, xmax = self.xminmax() - xwidth = xmax - xmin - scale = xwidth / maxcorr - scale = scale * korr for node, forcevec in zip(self.nodes, forcevecs): - corrvec = forcevec * scale + corrvec = forcevec * korr node.shift(corrvec) def squeeze_dim(self): @@ -273,16 +272,16 @@ return Vector(lonely).norm2() def lonelyness(self): - # square norm of lonelynesses + # sum norm of lonelynesses lonely = 0.0 for node in self.nodes: lonely += node.lonelyness() return lonely / len(self.nodes) def order(self): - sorter = [(node.position[0], node) for node in self.nodes] + sorter = [(node.position[0], node.name, node) for node in self.nodes] sorter.sort() - return [node for x, node in sorter] + return [node for x, x, node in sorter] def display(self): for node in self.order(): @@ -297,9 +296,15 @@ def d(): e() def e(): f() def f(): a() - sim = DemoSim([a, b, c, d, e, f]) + sim = SimGraph([a, b, c, d, e, f]) + sim.sim_all(0.9, 50) + return sim + def test_singleton(): + def s(): pass + sim = SimGraph([s]) sim.sim_all(0.9, 50) return sim g = SpaceGraph(test()) g.addgraph(test()) g.addgraph(test()) + g.addgraph(test_singleton()) Modified: pypy/dist/pypy/translator/locality/simulation.py ============================================================================== --- pypy/dist/pypy/translator/locality/simulation.py (original) +++ pypy/dist/pypy/translator/locality/simulation.py Mon Oct 31 15:49:34 2005 @@ -80,6 +80,9 @@ for node in self.callers: freq = self.sim.transitions[ (node, self) ] ret.append( (-freq, node) ) + # if there is nothing, link it to itself + if not ret: + ret.append( (-1, self) ) ret.sort() freqs, nodes = zip(*ret) return nodes, [-freq for freq in freqs] From pedronis at codespeak.net Mon Oct 31 15:56:41 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 15:56:41 +0100 (CET) Subject: [pypy-svn] r19237 - in pypy/release/0.8.x/pypy: module/sys tool Message-ID: <20051031145641.AB92F27B62@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 15:56:40 2005 New Revision: 19237 Modified: pypy/release/0.8.x/pypy/module/sys/version.py pypy/release/0.8.x/pypy/tool/makerelease.py Log: bump version number -> 0.8 to be merged back to the trunk then Modified: pypy/release/0.8.x/pypy/module/sys/version.py ============================================================================== --- pypy/release/0.8.x/pypy/module/sys/version.py (original) +++ pypy/release/0.8.x/pypy/module/sys/version.py Mon Oct 31 15:56:40 2005 @@ -8,7 +8,7 @@ CPYTHON_VERSION = (2, 4, 1, "alpha", 42) CPYTHON_API_VERSION = 1012 -PYPY_VERSION = (0, 7, 1, "alpha", '?') +PYPY_VERSION = (0, 8, 0, "alpha", '?') # the last item is replaced by the svn revision ^^^ SVN_URL = "$HeadURL: http://codespeak.net/svn/pypy/dist/pypy/module/sys/version.py $"[10:-28] Modified: pypy/release/0.8.x/pypy/tool/makerelease.py ============================================================================== --- pypy/release/0.8.x/pypy/tool/makerelease.py (original) +++ pypy/release/0.8.x/pypy/tool/makerelease.py Mon Oct 31 15:56:40 2005 @@ -5,7 +5,7 @@ log = py.log.Producer("log") logexec = py.log.Producer("exec") -BASEURL = "file:///svn/pypy/release/0.7.x" +BASEURL = "file:///svn/pypy/release/0.8.x" DDIR = py.path.local('/www/codespeak.net/htdocs/download/pypy') def usage(): From mwh at codespeak.net Mon Oct 31 16:00:50 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 31 Oct 2005 16:00:50 +0100 (CET) Subject: [pypy-svn] r19238 - pypy/release/0.8.x Message-ID: <20051031150050.F288F27B62@code1.codespeak.net> Author: mwh Date: Mon Oct 31 16:00:50 2005 New Revision: 19238 Modified: pypy/release/0.8.x/README Log: A somewhat more generic and time-agnostic README file. (If this isn't what we want, I can change it back). Points to not-yet-optimum urls. Modified: pypy/release/0.8.x/README ============================================================================== --- pypy/release/0.8.x/README (original) +++ pypy/release/0.8.x/README Mon Oct 31 16:00:50 2005 @@ -1,35 +1,36 @@ ======================================================= -PyPy: Python in Python implementation / Version 0.7.0 +PyPy: Python in Python implementation / Version 0.8.0 ======================================================= -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. +PyPy is an implementation of the Python programming language, written +in Python. -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 is very much a work in progress, but can already build a +self-contained Python implementation that is completey independent of +Python. - pypy/doc/getting-started.txt (local if you got a tarball) +For more, we invite you to head over to our getting-started document: - http://codespeak.net/pypy/dist/pypy/doc/getting-started.html + pypy/doc/getting-started.txt + (local if you got a tarball or svn checkout) -which gives you many good starting and entry points into -playing with PyPy. It will also point you to our -documentation section which is generated from information -in the pypy/doc directory. + http://codespeak.net/pypy/dist/pypy/doc/getting-started.html -Our online release announcement has some more -information about the specific PyPy-0.7.0 release: +which gives you many good starting and entry points into playing with +PyPy. It will also point you to our documentation section which is +generated from information in the pypy/doc directory. - pypy/doc/release-0.7.0.txt or - http://codespeak.net/pypy/dist/pypy/doc/release-0.7.0.html +For more information in what's new in this release, please read the +release announcment: -Please note that the last 9 months of PyPy development -have been funded by the European Union through its research -programme. + pypy/doc/release-0.8.0.txt + http://codespeak.net/pypy/dist/pypy/doc/release-0.8.0.html -Enjoy and send us feedback! +Since December 2004, the development of PyPy has been funded by the +European Union's research programme. For more information on this +aspect of the project please visit http://pypy.org/. + +Enjoy and send us feedback! the pypy-dev team From mwh at codespeak.net Mon Oct 31 16:02:09 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 31 Oct 2005 16:02:09 +0100 (CET) Subject: [pypy-svn] r19239 - pypy/release/0.8.x Message-ID: <20051031150209.8EB8E27B64@code1.codespeak.net> Author: mwh Date: Mon Oct 31 16:02:08 2005 New Revision: 19239 Modified: pypy/release/0.8.x/README Log: more accuracy Modified: pypy/release/0.8.x/README ============================================================================== --- pypy/release/0.8.x/README (original) +++ pypy/release/0.8.x/README Mon Oct 31 16:02:08 2005 @@ -20,8 +20,8 @@ PyPy. It will also point you to our documentation section which is generated from information in the pypy/doc directory. -For more information in what's new in this release, please read the -release announcment: +For information in what's new in this release, please read the release +announcment: pypy/doc/release-0.8.0.txt http://codespeak.net/pypy/dist/pypy/doc/release-0.8.0.html From ale at codespeak.net Mon Oct 31 16:02:47 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 31 Oct 2005 16:02:47 +0100 (CET) Subject: [pypy-svn] r19240 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031150247.7CE2227B62@code1.codespeak.net> Author: ale Date: Mon Oct 31 16:02:46 2005 New Revision: 19240 Modified: pypy/release/0.8.x/pypy/doc/contributor.txt Log: Updated the list of contributors Modified: pypy/release/0.8.x/pypy/doc/contributor.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/contributor.txt (original) +++ pypy/release/0.8.x/pypy/doc/contributor.txt Mon Oct 31 16:02:46 2005 @@ -6,38 +6,50 @@ code base, ordered by number of commits (which is certainly not a very appropriate measure but it's something):: - Armin Rigo - Samuele Pedroni - Holger Krekel - Michael Hudson - Christian Tismer - Seo Sanghyeon - Alex Martelli - Stefan Schwarzer - Tomek Meka - Patrick Maupin - Carl Friedrich Bolz - Bob Ippolito - Anders Chrigstrom - Jacob Hallen - Marius Gedminas - Laura Creighton - 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 + Armin Rigo + Samuele Pedroni + Christian Tismer + Holger Krekel + Michael Hudson + Carl Friedrich Bolz + Eric van Riet Paap + Anders Chrigstrom + Richard Emslie + Anders Lehmann + Seo Sanghyeon + Alex Martelli + Ludovic Aubry + Adrien Di Mascio + Stefan Schwarzer + Tomek Meka <> + Patrick Maupin + Bob Ippolito + Jacob Hallen + Laura Creighton + Marius Gedminas + Niklaus Haldimann + Amaury Forgeot d Arc + Guido van Rossum + Stephan Diehl <> + Dinu Gherman + Guenter Jantzen + Rocco Moretti + Boris Feigin + Olivier Dormond + Valentino Volonghi + Brian Dorsey + Jonathan David Riehl + Andreas Friedge + Jens-Uwe Mager + Bert Freudenberg + Alan McIntyre + Anders Qvist + Ignas Mikalajunas + Lutz Paelike + Jacek Generowicz + Andrew Thompson + Gintautas Miliauskas <> + Ben Young + Alexander Schremm + Michael Chermside + From pedronis at codespeak.net Mon Oct 31 16:11:52 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 16:11:52 +0100 (CET) Subject: [pypy-svn] r19241 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031151152.C574B27B62@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 16:11:52 2005 New Revision: 19241 Added: pypy/release/0.8.x/pypy/doc/getting-started.txt - copied unchanged from r19240, pypy/release/0.8.x/pypy/doc/getting-started-0.8.txt Removed: pypy/release/0.8.x/pypy/doc/getting-started-0.8.txt Log: fix the name for the refs. From ale at codespeak.net Mon Oct 31 16:17:32 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 31 Oct 2005 16:17:32 +0100 (CET) Subject: [pypy-svn] r19242 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031151732.361F127B62@code1.codespeak.net> Author: ale Date: Mon Oct 31 16:17:31 2005 New Revision: 19242 Modified: pypy/release/0.8.x/pypy/doc/contributor.txt Log: Removed a few which were not in the list at 0.7, and hasn't contributed since Corrected Alexander Schremmer's name Modified: pypy/release/0.8.x/pypy/doc/contributor.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/contributor.txt (original) +++ pypy/release/0.8.x/pypy/doc/contributor.txt Mon Oct 31 16:17:31 2005 @@ -44,12 +44,10 @@ Bert Freudenberg Alan McIntyre Anders Qvist - Ignas Mikalajunas Lutz Paelike Jacek Generowicz Andrew Thompson - Gintautas Miliauskas <> Ben Young - Alexander Schremm + Alexander Schremmer Michael Chermside From ale at codespeak.net Mon Oct 31 16:20:24 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 31 Oct 2005 16:20:24 +0100 (CET) Subject: [pypy-svn] r19244 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031152024.EC3C727B6D@code1.codespeak.net> Author: ale Date: Mon Oct 31 16:20:24 2005 New Revision: 19244 Modified: pypy/release/0.8.x/pypy/doc/contributor.txt Log: removed email addresses Modified: pypy/release/0.8.x/pypy/doc/contributor.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/contributor.txt (original) +++ pypy/release/0.8.x/pypy/doc/contributor.txt Mon Oct 31 16:20:24 2005 @@ -6,48 +6,48 @@ code base, ordered by number of commits (which is certainly not a very appropriate measure but it's something):: - Armin Rigo - Samuele Pedroni - Christian Tismer - Holger Krekel - Michael Hudson - Carl Friedrich Bolz - Eric van Riet Paap - Anders Chrigstrom - Richard Emslie - Anders Lehmann - Seo Sanghyeon - Alex Martelli - Ludovic Aubry - Adrien Di Mascio - Stefan Schwarzer - Tomek Meka <> - Patrick Maupin - Bob Ippolito - Jacob Hallen - Laura Creighton - Marius Gedminas - Niklaus Haldimann - Amaury Forgeot d Arc - Guido van Rossum - Stephan Diehl <> - Dinu Gherman - Guenter Jantzen - Rocco Moretti - Boris Feigin - Olivier Dormond - Valentino Volonghi - Brian Dorsey - Jonathan David Riehl - Andreas Friedge - Jens-Uwe Mager - Bert Freudenberg - Alan McIntyre - Anders Qvist - Lutz Paelike - Jacek Generowicz - Andrew Thompson - Ben Young - Alexander Schremmer - Michael Chermside + Armin Rigo + Samuele Pedroni + Christian Tismer + Holger Krekel + Michael Hudson + Carl Friedrich Bolz + Eric van Riet Paap + Anders Chrigstrom + Richard Emslie + Anders Lehmann + Seo Sanghyeon + Alex Martelli + Ludovic Aubry + Adrien Di Mascio + Stefan Schwarzer + Tomek Meka + Patrick Maupin + Bob Ippolito + Jacob Hallen + Laura Creighton + Marius Gedminas + Niklaus Haldimann + Amaury Forgeot d Arc + Guido van Rossum + Stephan Diehl + Dinu Gherman + Guenter Jantzen + Rocco Moretti + Boris Feigin + Olivier Dormond + Valentino Volonghi + Brian Dorsey + Jonathan David Riehl + Andreas Friedge + Jens-Uwe Mager + Bert Freudenberg + Alan McIntyre + Anders Qvist + Lutz Paelike + Jacek Generowicz + Andrew Thompson + Ben Young + Alexander Schremmer + Michael Chermside From pedronis at codespeak.net Mon Oct 31 16:28:26 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 16:28:26 +0100 (CET) Subject: [pypy-svn] r19248 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031152826.6C5F127B66@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 16:28:25 2005 New Revision: 19248 Modified: pypy/release/0.8.x/pypy/doc/architecture.txt Log: test Modified: pypy/release/0.8.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.8.x/pypy/doc/architecture.txt Mon Oct 31 16:28:25 2005 @@ -373,10 +373,10 @@ `translation document`_. There is a graph_ that gives an overview over the whole process. -Status of the implementation (Aug 2005) +Status of the implementation (Oct 2005) ========================================== -With the pypy-0.7.0 release we have a static self-contained +With the pypy-0.8.0 XXX updat me! 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 From ale at codespeak.net Mon Oct 31 16:45:24 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 31 Oct 2005 16:45:24 +0100 (CET) Subject: [pypy-svn] r19249 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031154524.BE85127B64@code1.codespeak.net> Author: ale Date: Mon Oct 31 16:45:24 2005 New Revision: 19249 Modified: pypy/release/0.8.x/pypy/doc/release-0.8.0.txt Log: First draft of release announcement. I have trunkated the contributor list to the 6 most active developer and point to contributor.html for the rest. Please comment Modified: pypy/release/0.8.x/pypy/doc/release-0.8.0.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/release-0.8.0.txt (original) +++ pypy/release/0.8.x/pypy/doc/release-0.8.0.txt Mon Oct 31 16:45:24 2005 @@ -1,25 +1,23 @@ -pypy-0.7.0: first PyPy-generated Python Implementations +pypy-0.8.0: Translatable compiler/parser and more speed ============================================================== -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 release -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 +The highlights of this third release of PyPy are: -- a translation choice of using a refcounting or Boehm - garbage collectors - -- the ability to translate with or without thread support - -- very complete language-level compliancy with CPython 2.4.1 +- Translatable parser and AST compiler +- Speed enhancements. Translated PyPy is about 10 times slower + than CPython on pystones (release-0.7.0 was about 200 times + slower) + +The release includes the snapshots of the following interesting +sub projects: + +- a socket module +- the start of a stackless implementation +- the OOtyper. A rtyper replacement for highlevel backends + (squeak, ...) +- A javascript backend +- A (PPC) assembler backend What is PyPy (about)? ------------------------------------------------ @@ -52,7 +50,7 @@ PyPy Homepage: http://codespeak.net/pypy/ The interpreter and object model implementations shipped with -the 0.7 version can run on their own and implement the core +the 0.8 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. @@ -60,14 +58,10 @@ Ongoing work and near term goals --------------------------------- -PyPy has been developed during approximately 15 coding sprints +PyPy has been developed during approximately 16 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. +one-week meetings to follow. PyPy has been a community effort from the start and it would not have got that far without the coding and feedback support @@ -76,7 +70,6 @@ contact points: http://codespeak.net/pypy/dist/pypy/doc/contact.html - contributor list: http://codespeak.net/pypy/dist/pypy/doc/contributor.html have fun, @@ -86,12 +79,7 @@ Armin Rigo, Samuele Pedroni, Holger Krekel, Christian Tismer, Carl Friedrich Bolz, Michael Hudson, - Eric 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 ... + and many contributors: http://codespeak.net/pypy/dist/pypy/doc/contributor.html PyPy development and activities happen as an open source project and with the support of a consortium partially funded by a two From mwh at codespeak.net Mon Oct 31 16:52:56 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 31 Oct 2005 16:52:56 +0100 (CET) Subject: [pypy-svn] r19251 - pypy/extradoc/talk/pycon2006 Message-ID: <20051031155256.92EF927B62@code1.codespeak.net> Author: mwh Date: Mon Oct 31 16:52:56 2005 New Revision: 19251 Modified: pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt Log: bump this somewhere over the 250 word suggested lower limit :) any final comments? Modified: pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt (original) +++ pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt Mon Oct 31 16:52:56 2005 @@ -28,13 +28,53 @@ -------------------- - Introduction to PyPy. + + + PyPy is an implementation of Python, written in Python. + + Aims for more flexibility and performance than existing + implementations. + - Demo of pypy-c. + + + "pypy-c" is the name of the binary produced by the translation + process. + + Will just run some python commands interactively to show how + similar we are to CPython. + - Overview. -- Our Toolchain: - + The Flow Object Space. - + The Annotator. - + The RTyper. - + The Low Level Backend(s). + + + The interpreter/object space split. + + One sentence description of each part of the toolchain. + +- Our Toolchain (1): The Flow Object Space. + + + The FlowObjectSpace abstractly interprets a function to build a + control flow graph of its structure. + + Works on function objects, not source code. + + Basically stable since early 2005, about 2000 lines of code. + +- Our Toolchain (2): The Annotator. + + + The RPythonAnnotator analyses an RPython program to infer types + and inter-function control flow. + + Works on the graphs produced by the FlowObjectSpace. + + More or less stable since early summer 2005, about 4000 lines of code. + +- Our Toolchain (3): The RTyper. + + + Converts the still-fairly-high-level output of the annotator into + lower level operations that are easier to translate into languages + like C. + + In particular, removes polymorphic calls from the graph. + + Basically working since summer 2005, restructuring in progress at + time of writing. About 10000 lines of code. + +- Our Toolchain (4): The Low Level Backend(s). + + + Take the low-level operations produced by the RTyper and converts + to a low-level language. + + At time of writing, C and LLVM are the supported targets. + + Working though not stable from spring 2005. C backend about 4000 + lines of code. Intended audience ----------------- From mwh at codespeak.net Mon Oct 31 17:04:44 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 31 Oct 2005 17:04:44 +0100 (CET) Subject: [pypy-svn] r19253 - pypy/dist/pypy/doc/weekly Message-ID: <20051031160444.086AF27B64@code1.codespeak.net> Author: mwh Date: Mon Oct 31 17:04:44 2005 New Revision: 19253 Modified: pypy/dist/pypy/doc/weekly/log Log: some stuff for next week's "this week in pypy" did anything noteworthy get discussed over the weekend? Modified: pypy/dist/pypy/doc/weekly/log ============================================================================== --- pypy/dist/pypy/doc/weekly/log (original) +++ pypy/dist/pypy/doc/weekly/log Mon Oct 31 17:04:44 2005 @@ -4,3 +4,15 @@ http://tismerysoft.de/pypy/irc-logs/pypy/%23pypy.log.20051027 around 13:30 server time. +2005-10-28 mwh + + I wrote an import analysis tool; a HTML report is at: + http://starship.python.net/crew/mwh/importfunhtml/pypy/ + I also posted some results to pypy-dev: + http://codespeak.net/pipermail/pypy-dev/2005q4/002563.html + http://codespeak.net/pipermail/pypy-dev/2005q4/002565.html + +2005-10-31 mwh + + We had a meeting about the 0.8.0 release. + http://tismerysoft.de/pypy/irc-logs/pypy-sync/%23pypy-sync.log.20051031 \ No newline at end of file From arigo at codespeak.net Mon Oct 31 17:21:30 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 17:21:30 +0100 (CET) Subject: [pypy-svn] r19259 - pypy/extradoc/talk/pycon2006 Message-ID: <20051031162130.F19E027B61@code1.codespeak.net> Author: arigo Date: Mon Oct 31 17:21:28 2005 New Revision: 19259 Modified: pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt Log: "Just" looks negative when we read quickly. Modified: pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt ============================================================================== --- pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt (original) +++ pypy/extradoc/talk/pycon2006/pypy-selfcontained.txt Mon Oct 31 17:21:28 2005 @@ -37,7 +37,7 @@ + "pypy-c" is the name of the binary produced by the translation process. - + Will just run some python commands interactively to show how + + We will run some python commands interactively to show how similar we are to CPython. - Overview. From pedronis at codespeak.net Mon Oct 31 17:32:14 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 17:32:14 +0100 (CET) Subject: [pypy-svn] r19260 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031163214.712CF27B64@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 17:32:13 2005 New Revision: 19260 Modified: pypy/release/0.8.x/pypy/doc/architecture.txt Log: first pass at updating architecture.txt Modified: pypy/release/0.8.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.8.x/pypy/doc/architecture.txt Mon Oct 31 17:32:13 2005 @@ -8,9 +8,6 @@ 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 - - Mission statement ==================== @@ -115,11 +112,12 @@ 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.) +(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 (living under +`interpreter/astcompiler/`_) is now integrated and is translated with +the rest of PyPy. In addition to storing bytecode, code objects also know how to create a *frame* object which has the responsibility to @@ -376,24 +374,31 @@ Status of the implementation (Oct 2005) ========================================== -With the pypy-0.8.0 XXX updat me! 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. +With the pypy-0.8.0 release we have integrated our AST compiler with +the rest of PyPy. The compiler gets translated with the rest to a +static self-contained version of our `standard interpreter`_. Like +with 0.7.0 this version is `very compliant`_ to CPython 2.4.1 but you +can still not run too many existing programs on it because we are +still missing a number of C-modules like socket or support for process +creation. + +The self-contained PyPy version (single-threaded and using the +`Boehm-Demers-Weiser garbage collector`_) now runs around 10-20 times +slower than CPython, this is the result of optimising, adding short +cuts for some common paths in our interpreter, and adding relatively +straightforward optimisation transforms to our tool chain, like inlining +paired with simple escape analysis to remove unnecessary heap allocations. +We still have some way to go, and we still expect most of our speed +will come from our Just-In-Time compiler work, which we barely started +at the moment. + +With the 0.8.0 release the "thunk" object space can also be translated +(see `getting started`_), obtaining a self-contained version of PyPy +with its feature (and some speed degradation), show-casing at a small +scale how our whole tool-chain supports flexibility from the interpreter +written in Python to the resulting self-contained executable. + +XXX update numbers Our rather complete and Python 2.4-compliant interpreter consists of about 30'000-50'000 lines of code (depending on the way you @@ -406,11 +411,15 @@ .. _`statistics web page`: http://codespeak.net/~hpk/pypy-stat/ .. _`very compliant`: http://codespeak.net/~hpk/pypy-testresult/ -.. _`300 times slower`: faq.html#whysoslow - +.. _`Boehm-Demers-Weiser garbage collector`: http://www.hpl.hp.com/personal/Hans_Boehm/gc/ .. _`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 +.. _`getting started`: getting-started.html + .. include:: _ref.txt + + + From pedronis at codespeak.net Mon Oct 31 17:46:28 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 17:46:28 +0100 (CET) Subject: [pypy-svn] r19264 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031164628.D0DB127B64@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 17:46:28 2005 New Revision: 19264 Modified: pypy/release/0.8.x/pypy/doc/architecture.txt Log: update LOCs Modified: pypy/release/0.8.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.8.x/pypy/doc/architecture.txt Mon Oct 31 17:46:28 2005 @@ -378,7 +378,7 @@ the rest of PyPy. The compiler gets translated with the rest to a static self-contained version of our `standard interpreter`_. Like with 0.7.0 this version is `very compliant`_ to CPython 2.4.1 but you -can still not run too many existing programs on it because we are +can not yet run too many existing programs on it because we are still missing a number of C-modules like socket or support for process creation. @@ -394,19 +394,17 @@ With the 0.8.0 release the "thunk" object space can also be translated (see `getting started`_), obtaining a self-contained version of PyPy -with its feature (and some speed degradation), show-casing at a small +with its features (and some speed degradation), show-casing at a small scale how our whole tool-chain supports flexibility from the interpreter written in Python to the resulting self-contained executable. -XXX update numbers - 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 +standard library modules ported from C, PyPy is now 138'000 +lines of code and 32'000 lines of tests. Refer to the `statistics web page`_ for more detailed information. .. _`statistics web page`: http://codespeak.net/~hpk/pypy-stat/ From pedronis at codespeak.net Mon Oct 31 18:01:29 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 18:01:29 +0100 (CET) Subject: [pypy-svn] r19266 - pypy/release/0.8.x Message-ID: <20051031170129.65D2327B64@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 18:01:28 2005 New Revision: 19266 Modified: pypy/release/0.8.x/README Log: seems good, fixed some typos Modified: pypy/release/0.8.x/README ============================================================================== --- pypy/release/0.8.x/README (original) +++ pypy/release/0.8.x/README Mon Oct 31 18:01:28 2005 @@ -6,7 +6,7 @@ in Python. PyPy is very much a work in progress, but can already build a -self-contained Python implementation that is completey independent of +self-contained Python implementation that is completely independent of Python. For more, we invite you to head over to our getting-started document: @@ -21,7 +21,7 @@ generated from information in the pypy/doc directory. For information in what's new in this release, please read the release -announcment: +announcement: pypy/doc/release-0.8.0.txt http://codespeak.net/pypy/dist/pypy/doc/release-0.8.0.html From arigo at codespeak.net Mon Oct 31 18:05:43 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 18:05:43 +0100 (CET) Subject: [pypy-svn] r19268 - pypy/dist/pypy/translator/goal Message-ID: <20051031170543.F1DE327B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 18:05:41 2005 New Revision: 19268 Modified: pypy/dist/pypy/translator/goal/driver.py (props changed) Log: driver.py was marked executable but it's not actually a script. From arigo at codespeak.net Mon Oct 31 18:06:08 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 18:06:08 +0100 (CET) Subject: [pypy-svn] r19269 - pypy/release/0.8.x/pypy/translator/goal Message-ID: <20051031170608.7DECB27B66@code1.codespeak.net> Author: arigo Date: Mon Oct 31 18:06:08 2005 New Revision: 19269 Modified: pypy/release/0.8.x/pypy/translator/goal/driver.py (props changed) Log: driver.py was marked executable but it's not actually a script. From arigo at codespeak.net Mon Oct 31 18:09:00 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 18:09:00 +0100 (CET) Subject: [pypy-svn] r19270 - pypy/dist/pypy/tool/pytest Message-ID: <20051031170900.77F3227B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 18:08:54 2005 New Revision: 19270 Modified: pypy/dist/pypy/tool/pytest/genreportdata.py Log: genreportdata.py marked executable but missing the #! line Modified: pypy/dist/pypy/tool/pytest/genreportdata.py ============================================================================== --- pypy/dist/pypy/tool/pytest/genreportdata.py (original) +++ pypy/dist/pypy/tool/pytest/genreportdata.py Mon Oct 31 18:08:54 2005 @@ -1,3 +1,4 @@ +#! /usr/bin/env python import autopath import py import sys From ale at codespeak.net Mon Oct 31 18:13:32 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 31 Oct 2005 18:13:32 +0100 (CET) Subject: [pypy-svn] r19271 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031171332.26C2927B66@code1.codespeak.net> Author: ale Date: Mon Oct 31 18:13:32 2005 New Revision: 19271 Modified: pypy/release/0.8.x/pypy/doc/architecture.txt Log: typo Modified: pypy/release/0.8.x/pypy/doc/architecture.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/architecture.txt (original) +++ pypy/release/0.8.x/pypy/doc/architecture.txt Mon Oct 31 18:13:32 2005 @@ -109,7 +109,7 @@ when needed, by invoking a bytecode compiler. Code objects are a nicely preprocessed, structured representation of source code, and their main content is *bytecode*. We use the same compact bytecode format -than CPython 2.4. +as CPython 2.4. Our bytecode compiler is implemented as a chain of flexible passes (tokenizer, lexer, parser, abstract syntax tree builder, bytecode From arigo at codespeak.net Mon Oct 31 18:18:19 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 18:18:19 +0100 (CET) Subject: [pypy-svn] r19275 - pypy/dist/demo Message-ID: <20051031171819.64E2927B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 18:18:16 2005 New Revision: 19275 Modified: pypy/dist/demo/bpnn.py Log: Fixed the #! line. Modified: pypy/dist/demo/bpnn.py ============================================================================== --- pypy/dist/demo/bpnn.py (original) +++ pypy/dist/demo/bpnn.py Mon Oct 31 18:18:16 2005 @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python """ Translator Demo @@ -190,6 +190,7 @@ print 'Annotating...' a = t.annotate([]) a.simplify() + t.viewcg() print 'Specializing...' t.specialize() # enable this to see (some) lower-level Cish operations From arigo at codespeak.net Mon Oct 31 18:30:23 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 18:30:23 +0100 (CET) Subject: [pypy-svn] r19281 - pypy/release/0.8.x/pypy/translator/c/src Message-ID: <20051031173023.2FFBE27B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 18:30:22 2005 New Revision: 19281 Modified: pypy/release/0.8.x/pypy/translator/c/src/mem.h Log: Bug fix for 64-bit platforms. Modified: pypy/release/0.8.x/pypy/translator/c/src/mem.h ============================================================================== --- pypy/release/0.8.x/pypy/translator/c/src/mem.h (original) +++ pypy/release/0.8.x/pypy/translator/c/src/mem.h Mon Oct 31 18:30:22 2005 @@ -9,7 +9,8 @@ #define MAXIMUM_MALLOCABLE_SIZE (LONG_MAX-4096) #define OP_MAX_VARSIZE(numitems, itemtype, err) { \ - if (((unsigned)(numitems)) > (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype)))\ + if (((unsigned long)(numitems)) > \ + (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype))) \ FAIL_EXCEPTION(err, PyExc_MemoryError, "addr space overflow"); \ } From arigo at codespeak.net Mon Oct 31 18:31:28 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 18:31:28 +0100 (CET) Subject: [pypy-svn] r19282 - pypy/dist/pypy/translator/c/src Message-ID: <20051031173128.4F18B27B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 18:31:25 2005 New Revision: 19282 Modified: pypy/dist/pypy/translator/c/src/mem.h Log: Port r19263 from the 0.8 release branch. 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 Oct 31 18:31:25 2005 @@ -9,7 +9,8 @@ #define MAXIMUM_MALLOCABLE_SIZE (LONG_MAX-4096) #define OP_MAX_VARSIZE(numitems, itemtype, err) { \ - if (((unsigned)(numitems)) > (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype)))\ + if (((unsigned long)(numitems)) > \ + (MAXIMUM_MALLOCABLE_SIZE / sizeof(itemtype))) \ FAIL_EXCEPTION(err, PyExc_MemoryError, "addr space overflow"); \ } From ale at codespeak.net Mon Oct 31 19:14:00 2005 From: ale at codespeak.net (ale at codespeak.net) Date: Mon, 31 Oct 2005 19:14:00 +0100 (CET) Subject: [pypy-svn] r19288 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031181400.A0E4027B64@code1.codespeak.net> Author: ale Date: Mon Oct 31 19:13:59 2005 New Revision: 19288 Modified: pypy/release/0.8.x/pypy/doc/release-0.8.0.txt Log: Added mention of Thunk Object Space Modified: pypy/release/0.8.x/pypy/doc/release-0.8.0.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/release-0.8.0.txt (original) +++ pypy/release/0.8.x/pypy/doc/release-0.8.0.txt Mon Oct 31 19:13:59 2005 @@ -9,6 +9,8 @@ than CPython on pystones (release-0.7.0 was about 200 times slower) +- a translatable version of the Thunk Object space + The release includes the snapshots of the following interesting sub projects: From mwh at codespeak.net Mon Oct 31 19:15:25 2005 From: mwh at codespeak.net (mwh at codespeak.net) Date: Mon, 31 Oct 2005 19:15:25 +0100 (CET) Subject: [pypy-svn] r19289 - pypy/release/0.8.x/pypy/doc Message-ID: <20051031181525.A47D727B64@code1.codespeak.net> Author: mwh Date: Mon Oct 31 19:15:24 2005 New Revision: 19289 Modified: pypy/release/0.8.x/pypy/doc/release-0.8.0.txt Log: be a little cautious in the wording... Modified: pypy/release/0.8.x/pypy/doc/release-0.8.0.txt ============================================================================== --- pypy/release/0.8.x/pypy/doc/release-0.8.0.txt (original) +++ pypy/release/0.8.x/pypy/doc/release-0.8.0.txt Mon Oct 31 19:15:24 2005 @@ -19,7 +19,7 @@ - the OOtyper. A rtyper replacement for highlevel backends (squeak, ...) - A javascript backend -- A (PPC) assembler backend +- A limited (PPC) assembler backend What is PyPy (about)? ------------------------------------------------ From tismer at codespeak.net Mon Oct 31 20:50:49 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 20:50:49 +0100 (CET) Subject: [pypy-svn] r19295 - pypy/dist/pypy/translator/c Message-ID: <20051031195049.B119D27B64@code1.codespeak.net> Author: tismer Date: Mon Oct 31 20:50:48 2005 New Revision: 19295 Modified: pypy/dist/pypy/translator/c/database.py Log: added a flag that tells whether the database is completed Modified: pypy/dist/pypy/translator/c/database.py ============================================================================== --- pypy/dist/pypy/translator/c/database.py (original) +++ pypy/dist/pypy/translator/c/database.py Mon Oct 31 20:50:48 2005 @@ -32,6 +32,7 @@ from pypy.translator.c import gc gcpolicy = gc.RefcountingGcPolicy self.gcpolicy = gcpolicy(self, thread_enabled) + self.completed = False def gettypedefnode(self, T, varlength=1): if varlength <= 1: @@ -161,6 +162,7 @@ if i == show_i: dump() show_i += 1000 + self.completed = True if show_progress: dump() From tismer at codespeak.net Mon Oct 31 20:51:47 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 20:51:47 +0100 (CET) Subject: [pypy-svn] r19296 - pypy/dist/pypy/translator/c/src Message-ID: <20051031195147.520A927B64@code1.codespeak.net> Author: tismer Date: Mon Oct 31 20:51:44 2005 New Revision: 19296 Modified: pypy/dist/pypy/translator/c/src/addrinfo.h (contents, props changed) pypy/dist/pypy/translator/c/src/getaddrinfo.c (props changed) pypy/dist/pypy/translator/c/src/getnameinfo.c (props changed) pypy/dist/pypy/translator/c/src/ll__socket.h (props changed) pypy/dist/pypy/translator/c/src/stack.h (props changed) Log: fixeol Modified: pypy/dist/pypy/translator/c/src/addrinfo.h ============================================================================== --- pypy/dist/pypy/translator/c/src/addrinfo.h (original) +++ pypy/dist/pypy/translator/c/src/addrinfo.h Mon Oct 31 20:51:44 2005 @@ -1,177 +1,177 @@ -/* Copied from python 2.4.1: Modules/addrinfo.h */ -/* - * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef HAVE_GETADDRINFO - -/* - * Error return codes from getaddrinfo() - */ -#ifdef EAI_ADDRFAMILY -/* If this is defined, there is a conflicting implementation - in the C library, which can't be used for some reason. - Make sure it won't interfere with this emulation. */ - -#undef EAI_ADDRFAMILY -#undef EAI_AGAIN -#undef EAI_BADFLAGS -#undef EAI_FAIL -#undef EAI_FAMILY -#undef EAI_MEMORY -#undef EAI_NODATA -#undef EAI_NONAME -#undef EAI_SERVICE -#undef EAI_SOCKTYPE -#undef EAI_SYSTEM -#undef EAI_BADHINTS -#undef EAI_PROTOCOL -#undef EAI_MAX -#undef getaddrinfo -#define getaddrinfo fake_getaddrinfo -#endif /* EAI_ADDRFAMILY */ - -#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ -#define EAI_AGAIN 2 /* temporary failure in name resolution */ -#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ -#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ -#define EAI_FAMILY 5 /* ai_family not supported */ -#define EAI_MEMORY 6 /* memory allocation failure */ -#define EAI_NODATA 7 /* no address associated with hostname */ -#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ -#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ -#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ -#define EAI_SYSTEM 11 /* system error returned in errno */ -#define EAI_BADHINTS 12 -#define EAI_PROTOCOL 13 -#define EAI_MAX 14 - -/* - * Flag values for getaddrinfo() - */ -#ifdef AI_PASSIVE -#undef AI_PASSIVE -#undef AI_CANONNAME -#undef AI_NUMERICHOST -#undef AI_MASK -#undef AI_ALL -#undef AI_V4MAPPED_CFG -#undef AI_ADDRCONFIG -#undef AI_V4MAPPED -#undef AI_DEFAULT -#endif /* AI_PASSIVE */ - -#define AI_PASSIVE 0x00000001 /* get address to use bind() */ -#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ -#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ -/* valid flags for addrinfo */ -#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) - -#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ -#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ -#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ -#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ -/* special recommended flags for getipnodebyname */ -#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) - -#endif /* !HAVE_GETADDRINFO */ - -#ifndef HAVE_GETNAMEINFO - -/* - * Constants for getnameinfo() - */ -#ifndef NI_MAXHOST -#define NI_MAXHOST 1025 -#define NI_MAXSERV 32 -#endif /* !NI_MAXHOST */ - -/* - * Flag values for getnameinfo() - */ -#ifndef NI_NOFQDN -#define NI_NOFQDN 0x00000001 -#define NI_NUMERICHOST 0x00000002 -#define NI_NAMEREQD 0x00000004 -#define NI_NUMERICSERV 0x00000008 -#define NI_DGRAM 0x00000010 -#endif /* !NI_NOFQDN */ - -#endif /* !HAVE_GETNAMEINFO */ - -#ifndef HAVE_ADDRINFO -struct addrinfo { - int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ - int ai_family; /* PF_xxx */ - int ai_socktype; /* SOCK_xxx */ - int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ - size_t ai_addrlen; /* length of ai_addr */ - char *ai_canonname; /* canonical name for hostname */ - struct sockaddr *ai_addr; /* binary address */ - struct addrinfo *ai_next; /* next structure in linked list */ -}; -#endif /* !HAVE_ADDRINFO */ - -#ifndef HAVE_SOCKADDR_STORAGE -/* - * RFC 2553: protocol-independent placeholder for socket addresses - */ -#define _SS_MAXSIZE 128 -#ifdef HAVE_LONG_LONG -#define _SS_ALIGNSIZE (sizeof(PY_LONG_LONG)) -#else -#define _SS_ALIGNSIZE (sizeof(double)) -#endif /* HAVE_LONG_LONG */ -#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) -#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ - _SS_PAD1SIZE - _SS_ALIGNSIZE) - -struct sockaddr_storage { -#ifdef HAVE_SOCKADDR_SA_LEN - unsigned char ss_len; /* address length */ - unsigned char ss_family; /* address family */ -#else - unsigned short ss_family; /* address family */ -#endif /* HAVE_SOCKADDR_SA_LEN */ - char __ss_pad1[_SS_PAD1SIZE]; -#ifdef HAVE_LONG_LONG - PY_LONG_LONG __ss_align; /* force desired structure storage alignment */ -#else - double __ss_align; /* force desired structure storage alignment */ -#endif /* HAVE_LONG_LONG */ - char __ss_pad2[_SS_PAD2SIZE]; -}; -#endif /* !HAVE_SOCKADDR_STORAGE */ - -#ifdef __cplusplus -extern "C" { -#endif -extern void freehostent Py_PROTO((struct hostent *)); -#ifdef __cplusplus -} -#endif +/* Copied from python 2.4.1: Modules/addrinfo.h */ +/* + * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef HAVE_GETADDRINFO + +/* + * Error return codes from getaddrinfo() + */ +#ifdef EAI_ADDRFAMILY +/* If this is defined, there is a conflicting implementation + in the C library, which can't be used for some reason. + Make sure it won't interfere with this emulation. */ + +#undef EAI_ADDRFAMILY +#undef EAI_AGAIN +#undef EAI_BADFLAGS +#undef EAI_FAIL +#undef EAI_FAMILY +#undef EAI_MEMORY +#undef EAI_NODATA +#undef EAI_NONAME +#undef EAI_SERVICE +#undef EAI_SOCKTYPE +#undef EAI_SYSTEM +#undef EAI_BADHINTS +#undef EAI_PROTOCOL +#undef EAI_MAX +#undef getaddrinfo +#define getaddrinfo fake_getaddrinfo +#endif /* EAI_ADDRFAMILY */ + +#define EAI_ADDRFAMILY 1 /* address family for hostname not supported */ +#define EAI_AGAIN 2 /* temporary failure in name resolution */ +#define EAI_BADFLAGS 3 /* invalid value for ai_flags */ +#define EAI_FAIL 4 /* non-recoverable failure in name resolution */ +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_MEMORY 6 /* memory allocation failure */ +#define EAI_NODATA 7 /* no address associated with hostname */ +#define EAI_NONAME 8 /* hostname nor servname provided, or not known */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#define EAI_SOCKTYPE 10 /* ai_socktype not supported */ +#define EAI_SYSTEM 11 /* system error returned in errno */ +#define EAI_BADHINTS 12 +#define EAI_PROTOCOL 13 +#define EAI_MAX 14 + +/* + * Flag values for getaddrinfo() + */ +#ifdef AI_PASSIVE +#undef AI_PASSIVE +#undef AI_CANONNAME +#undef AI_NUMERICHOST +#undef AI_MASK +#undef AI_ALL +#undef AI_V4MAPPED_CFG +#undef AI_ADDRCONFIG +#undef AI_V4MAPPED +#undef AI_DEFAULT +#endif /* AI_PASSIVE */ + +#define AI_PASSIVE 0x00000001 /* get address to use bind() */ +#define AI_CANONNAME 0x00000002 /* fill ai_canonname */ +#define AI_NUMERICHOST 0x00000004 /* prevent name resolution */ +/* valid flags for addrinfo */ +#define AI_MASK (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST) + +#define AI_ALL 0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */ +#define AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */ +#define AI_ADDRCONFIG 0x00000400 /* only if any address is assigned */ +#define AI_V4MAPPED 0x00000800 /* accept IPv4-mapped IPv6 address */ +/* special recommended flags for getipnodebyname */ +#define AI_DEFAULT (AI_V4MAPPED_CFG | AI_ADDRCONFIG) + +#endif /* !HAVE_GETADDRINFO */ + +#ifndef HAVE_GETNAMEINFO + +/* + * Constants for getnameinfo() + */ +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#define NI_MAXSERV 32 +#endif /* !NI_MAXHOST */ + +/* + * Flag values for getnameinfo() + */ +#ifndef NI_NOFQDN +#define NI_NOFQDN 0x00000001 +#define NI_NUMERICHOST 0x00000002 +#define NI_NAMEREQD 0x00000004 +#define NI_NUMERICSERV 0x00000008 +#define NI_DGRAM 0x00000010 +#endif /* !NI_NOFQDN */ + +#endif /* !HAVE_GETNAMEINFO */ + +#ifndef HAVE_ADDRINFO +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif /* !HAVE_ADDRINFO */ + +#ifndef HAVE_SOCKADDR_STORAGE +/* + * RFC 2553: protocol-independent placeholder for socket addresses + */ +#define _SS_MAXSIZE 128 +#ifdef HAVE_LONG_LONG +#define _SS_ALIGNSIZE (sizeof(PY_LONG_LONG)) +#else +#define _SS_ALIGNSIZE (sizeof(double)) +#endif /* HAVE_LONG_LONG */ +#define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_char) * 2) +#define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(u_char) * 2 - \ + _SS_PAD1SIZE - _SS_ALIGNSIZE) + +struct sockaddr_storage { +#ifdef HAVE_SOCKADDR_SA_LEN + unsigned char ss_len; /* address length */ + unsigned char ss_family; /* address family */ +#else + unsigned short ss_family; /* address family */ +#endif /* HAVE_SOCKADDR_SA_LEN */ + char __ss_pad1[_SS_PAD1SIZE]; +#ifdef HAVE_LONG_LONG + PY_LONG_LONG __ss_align; /* force desired structure storage alignment */ +#else + double __ss_align; /* force desired structure storage alignment */ +#endif /* HAVE_LONG_LONG */ + char __ss_pad2[_SS_PAD2SIZE]; +}; +#endif /* !HAVE_SOCKADDR_STORAGE */ + +#ifdef __cplusplus +extern "C" { +#endif +extern void freehostent Py_PROTO((struct hostent *)); +#ifdef __cplusplus +} +#endif From arigo at codespeak.net Mon Oct 31 20:52:27 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 20:52:27 +0100 (CET) Subject: [pypy-svn] r19297 - in pypy/dist/pypy/translator: c c/test tool Message-ID: <20051031195227.C927E27B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 20:52:22 2005 New Revision: 19297 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/test/test_stackless.py pypy/dist/pypy/translator/c/test/test_standalone.py pypy/dist/pypy/translator/tool/cbuild.py Log: Generate a Makefile for stand-alone targets. (cbuild.py is quite messy, so this involved some refactoring...) Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Mon Oct 31 20:52:22 2005 @@ -5,7 +5,7 @@ from pypy.translator.c.extfunc import pre_include_code_lines from pypy.translator.gensupp import uniquemodulename, NameManager from pypy.translator.tool.cbuild import compile_c_module -from pypy.translator.tool.cbuild import build_executable +from pypy.translator.tool.cbuild import build_executable, CCompiler from pypy.translator.tool.cbuild import import_module_from_directory from pypy.rpython.rmodel import getfunctionptr from pypy.rpython.lltypesystem import lltype @@ -76,6 +76,8 @@ defines = defines) self.c_source_filename = py.path.local(cfile) self.extrafiles = extra + if self.standalone: + self.gen_makefile(targetdir) return cfile @@ -120,16 +122,21 @@ # signature: list-of-strings -> int return getfunctionptr(self.translator, self.translator.entrypoint) - def compile(self): - assert self.c_source_filename - assert not self._compiled + def getccompiler(self, extra_includes): # XXX for now, we always include Python.h from distutils import sysconfig python_inc = sysconfig.get_python_inc() - self.executable_name = build_executable( + return CCompiler( [self.c_source_filename] + self.extrafiles, - include_dirs = [autopath.this_dir, python_inc, str(self.targetdir)], - libraries=self.libraries) + include_dirs = [autopath.this_dir, python_inc] + extra_includes, + libraries = self.libraries) + + def compile(self): + assert self.c_source_filename + assert not self._compiled + compiler = self.getccompiler(extra_includes=[str(self.targetdir)]) + compiler.build() + self.executable_name = str(compiler.outputfilename) self._compiled = True return self.executable_name @@ -137,6 +144,46 @@ assert self._compiled return py.process.cmdexec('"%s" %s' % (self.executable_name, args)) + def gen_makefile(self, targetdir): + def write_list(lst, prefix): + for i, fn in enumerate(lst): + print >> f, prefix, fn, + if i < len(lst)-1: + print >> f, '\\' + else: + print >> f + prefix = ' ' * len(prefix) + + compiler = self.getccompiler(extra_includes=['.']) + cfiles = [] + ofiles = [] + for fn in compiler.cfilenames: + fn = py.path.local(fn).basename + assert fn.endswith('.c') + cfiles.append(fn) + ofiles.append(fn[:-2] + '.o') + + f = targetdir.join('Makefile').open('w') + print >> f, '# automatically generated Makefile' + print >> f + print >> f, 'TARGET =', py.path.local(compiler.outputfilename).basename + print >> f + write_list(cfiles, 'SOURCES =') + print >> f + write_list(ofiles, 'OBJECTS =') + print >> f + args = ['-l'+libname for libname in compiler.libraries] + print >> f, 'LIBS =', ' '.join(args) + args = ['-L'+path for path in compiler.library_dirs] + print >> f, 'LIBDIRS =', ' '.join(args) + args = ['-I'+path for path in compiler.include_dirs] + write_list(args, 'INCLUDEDIRS =') + print >> f + print >> f, 'CFLAGS =', ' '.join(compiler.compile_extra) + print >> f, 'LDFLAGS =', ' '.join(compiler.link_extra) + print >> f, MAKEFILE.strip() + f.close() + def translator2database(translator): pf = lltype.pyobjectptr(translator.entrypoint) @@ -345,6 +392,7 @@ fc.close() print >> f + # this function acts as the fallback for small sources for now. # Maybe we drop this completely if source splitting is the way # to go. Currently, I'm quite fine with keeping a working fallback. @@ -655,3 +703,16 @@ extra_compile_args = extra_compile_args, include_dirs = [PYPY_INCLUDE_DIR])]) ''' + +MAKEFILE = ''' +CC = gcc + +$(TARGET): $(OBJECTS) +\t$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBDIRS) $(LIBS) + +%.o: %.c +\t$(CC) $(CFLAGS) -o $@ -c $< $(INCLUDEDIRS) + +clean: +\trm -f $(OBJECTS) +''' Modified: pypy/dist/pypy/translator/c/test/test_stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_stackless.py (original) +++ pypy/dist/pypy/translator/c/test/test_stackless.py Mon Oct 31 20:52:22 2005 @@ -1,5 +1,4 @@ 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 from pypy.rpython.rstack import stack_unwind, stack_frames_depth, stack_too_big Modified: pypy/dist/pypy/translator/c/test/test_standalone.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_standalone.py (original) +++ pypy/dist/pypy/translator/c/test/test_standalone.py Mon Oct 31 20:52:22 2005 @@ -1,5 +1,4 @@ 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 Modified: pypy/dist/pypy/translator/tool/cbuild.py ============================================================================== --- pypy/dist/pypy/translator/tool/cbuild.py (original) +++ pypy/dist/pypy/translator/tool/cbuild.py Mon Oct 31 20:52:22 2005 @@ -254,55 +254,64 @@ return spawn(cmd, *args, **kwds) return spawn_and_log -def build_executable(cfilenames, outputfilename=None, include_dirs=None, - libraries=[], library_dirs=None): - from distutils.ccompiler import new_compiler - ext = '' - compile_extra = [] - link_extra = [] - - if not include_dirs: - include_dirs = [] - if not library_dirs: - library_dirs = [] - if not sys.platform in ('win32', 'darwin'): # xxx - libraries.append('m') - libraries.append('pthread') - compile_extra += ['-O2', '-pthread'] - link_extra += ['-pthread'] - if sys.platform == 'darwin': - include_dirs.append('/sw/include') - compile_extra += ['-O2'] - - if outputfilename is None: - outputfilename = py.path.local(cfilenames[0]).new(ext=ext) - else: - outputfilename = py.path.local(outputfilename) - - if sys.platform == 'darwin': - library_dirs=['/sw/lib'] - - compiler = new_compiler() - compiler.spawn = log_spawned_cmd(compiler.spawn) - objects = [] - for cfile in cfilenames: - cfile = py.path.local(cfile) - old = cfile.dirpath().chdir() - try: - res = compiler.compile([cfile.basename], - include_dirs=include_dirs, - extra_preargs=compile_extra) - assert len(res) == 1 - cobjfile = py.path.local(res[0]) - assert cobjfile.check() - objects.append(str(cobjfile)) - finally: - old.chdir() - compiler.link_executable(objects, str(outputfilename), - libraries=libraries, - extra_preargs=link_extra, - library_dirs=library_dirs) - return str(outputfilename) + +class CCompiler: + + def __init__(self, cfilenames, outputfilename=None, include_dirs=[], + libraries=[], library_dirs=[]): + self.cfilenames = cfilenames + ext = '' + self.compile_extra = [] + self.link_extra = [] + self.libraries = list(libraries) + self.include_dirs = list(include_dirs) + self.library_dirs = list(library_dirs) + if not sys.platform in ('win32', 'darwin'): # xxx + if 'm' not in self.libraries: + self.libraries.append('m') + if 'pthread' not in self.libraries: + self.libraries.append('pthread') + self.compile_extra += ['-O2', '-pthread'] + self.link_extra += ['-pthread'] + if sys.platform == 'darwin': + if '/sw/include' not in self.include_dirs: + self.include_dirs.append('/sw/include') + if '/sw/lib' not in self.library_dirs: + self.library_dirs.append('/sw/lib') + self.compile_extra += ['-O2'] + + if outputfilename is None: + self.outputfilename = py.path.local(cfilenames[0]).new(ext=ext) + else: + self.outputfilename = py.path.local(outputfilename) + + def build(self): + from distutils.ccompiler import new_compiler + compiler = new_compiler() + compiler.spawn = log_spawned_cmd(compiler.spawn) + objects = [] + for cfile in self.cfilenames: + cfile = py.path.local(cfile) + old = cfile.dirpath().chdir() + try: + res = compiler.compile([cfile.basename], + include_dirs=self.include_dirs, + extra_preargs=self.compile_extra) + assert len(res) == 1 + cobjfile = py.path.local(res[0]) + assert cobjfile.check() + objects.append(str(cobjfile)) + finally: + old.chdir() + compiler.link_executable(objects, str(self.outputfilename), + libraries=self.libraries, + extra_preargs=self.link_extra, + library_dirs=self.library_dirs) + +def build_executable(*args, **kwds): + compiler = CCompiler(*args, **kwds) + compiler.build() + return str(compiler.outputfilename) def check_boehm_presence(): from pypy.tool.udir import udir From tismer at codespeak.net Mon Oct 31 20:54:32 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 20:54:32 +0100 (CET) Subject: [pypy-svn] r19298 - pypy/dist/pypy/translator Message-ID: <20051031195432.A070527B64@code1.codespeak.net> Author: tismer Date: Mon Oct 31 20:54:31 2005 New Revision: 19298 Modified: pypy/dist/pypy/translator/translator.py Log: added some provision to get the complete callgraph. The problem was that we do some initial callgraph, but in the later transformations, we don't update that, and it would be not so trivial to enforce this. Therefore, I created a property complete_callgraph, which is recomputed whenever new graphs are added. Modified: pypy/dist/pypy/translator/translator.py ============================================================================== --- pypy/dist/pypy/translator/translator.py (original) +++ pypy/dist/pypy/translator/translator.py Mon Oct 31 20:54:31 2005 @@ -15,7 +15,7 @@ log = py.log.Producer("getflowgraph") py.log.setconsumer("getflowgraph", ansi_log) -class Translator: +class Translator(object): def __init__(self, func=None, verbose=False, simplifying=True, do_imports_immediately=True, @@ -37,6 +37,8 @@ self.frozen = False # when frozen, no more flowgraphs can be generated #self.concretetypes = {} # see getconcretetype() #self.ctlist = [] # " + # the following is an index into self.functions from where to check + self._callgraph_complete = 0 if self.entrypoint: self.getflowgraph() @@ -161,6 +163,7 @@ checkgraph(graph) def specialize(self, **flags): + self._callgraph_complete = 0 if self.annotator is None: raise ValueError("you need to call annotate() first") if self.rtyper is not None: @@ -172,6 +175,7 @@ self.rtyper.specialize(**flags) def backend_optimizations(self, **kwds): + self._callgraph_complete = 0 from pypy.translator.backendopt.all import backend_optimizations backend_optimizations(self, **kwds) @@ -364,3 +368,34 @@ ## result = self.concretetypes[cls, args] = cls(self, *args) ## self.ctlist.append(result) ## return result + + def get_complete_callgraph(self): + if self._callgraph_complete < len(self.functions): + self._complete_callgraph() + return self.callgraph + complete_callgraph = property(get_complete_callgraph) + + def _complete_callgraph(self): + # walk through all functions, which may grow + # if we pull new graphs in. + graphs = self.flowgraphs + funcs = self.functions + was_frozen = self.frozen + self.frozen = False + complete = self._callgraph_complete + while complete < len(funcs): + sofar = len(funcs) + for func in funcs[complete:]: + graph = graphs[func] + for block in graph.iterblocks(): + for op in block.operations: + if op.opname == 'direct_call': + fnarg = op.args[0] + if isinstance(fnarg, Constant): + fnptr = fnarg.value + fn = fnptr._obj._callable + fg = self.getflowgraph(fn, called_by = func, + call_tag = block) + complete = sofar + self.frozen = was_frozen + self._callgraph_complete = complete From tismer at codespeak.net Mon Oct 31 20:57:09 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 20:57:09 +0100 (CET) Subject: [pypy-svn] r19299 - in pypy/dist/pypy/translator: goal tool Message-ID: <20051031195709.3FDA327B64@code1.codespeak.net> Author: tismer Date: Mon Oct 31 20:57:06 2005 New Revision: 19299 Modified: pypy/dist/pypy/translator/goal/targetrpystonedalone.py pypy/dist/pypy/translator/tool/graphpage.py Log: use the complete_callgraph property now. This has the advantage that the picture gets much more complete. Sometimes it now gets over-complete, because transitions which already existed before some transformations, may be found twice, now. A cleanup may be needed at some point, but for now it is good enough. See for instance targetrpystonedalone.py, where I have put a recursion just for testing it with graphics (and actually stackless). The recursion in pysone_main is shown twice, now. Modified: pypy/dist/pypy/translator/goal/targetrpystonedalone.py ============================================================================== --- pypy/dist/pypy/translator/goal/targetrpystonedalone.py (original) +++ pypy/dist/pypy/translator/goal/targetrpystonedalone.py Mon Oct 31 20:57:06 2005 @@ -18,6 +18,8 @@ (VERSION, loops, benchtime) + '\n' + ( "This machine benchmarks at %f pystones/second" % stones)) os.write(1, s) + if loops == 12345: + pystones_main(loops-1) def richards_main(iterations): s = "Richards benchmark (RPython) starting...\n" Modified: pypy/dist/pypy/translator/tool/graphpage.py ============================================================================== --- pypy/dist/pypy/translator/tool/graphpage.py (original) +++ pypy/dist/pypy/translator/tool/graphpage.py Mon Oct 31 20:57:06 2005 @@ -281,7 +281,7 @@ translator = self.translator # show the call graph - callgraph = translator.callgraph.values() + callgraph = translator.complete_callgraph.values() functions = list(translator.functions) if len(functions) > huge: @@ -316,7 +316,7 @@ class LocalizedCallGraphPage(BaseTranslatorPage): - """A GraphPage showing a the localized call graph for a function, + """A GraphPage showing the localized call graph for a function, that means just including direct callers and callees""" def graph_name(self, func0): From pedronis at codespeak.net Mon Oct 31 21:16:59 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 21:16:59 +0100 (CET) Subject: [pypy-svn] r19301 - pypy/dist/pypy/translator/goal Message-ID: <20051031201659.1A1F127B64@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 21:16:57 2005 New Revision: 19301 Removed: pypy/dist/pypy/translator/goal/runtranslate.sh Log: osbolete From tismer at codespeak.net Mon Oct 31 21:35:51 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 21:35:51 +0100 (CET) Subject: [pypy-svn] r19302 - pypy/dist/pypy/translator/goal Message-ID: <20051031203551.5D54527B64@code1.codespeak.net> Author: tismer Date: Mon Oct 31 21:35:50 2005 New Revision: 19302 Modified: pypy/dist/pypy/translator/goal/driver.py Log: typo, again Modified: pypy/dist/pypy/translator/goal/driver.py ============================================================================== --- pypy/dist/pypy/translator/goal/driver.py (original) +++ pypy/dist/pypy/translator/goal/driver.py Mon Oct 31 21:35:50 2005 @@ -263,7 +263,7 @@ # task_llinterpret = taskdef(task_llinterpret, ['?backendopt', 'rtype'], - "LLInterpeting") + "LLInterpreting") def task_source_llvm(self): # xxx messy translator = self.translator From tismer at codespeak.net Mon Oct 31 21:37:55 2005 From: tismer at codespeak.net (tismer at codespeak.net) Date: Mon, 31 Oct 2005 21:37:55 +0100 (CET) Subject: [pypy-svn] r19303 - in pypy/dist/pypy/translator/c: . test Message-ID: <20051031203755.CA27F27B64@code1.codespeak.net> Author: tismer Date: Mon Oct 31 21:37:54 2005 New Revision: 19303 Modified: pypy/dist/pypy/translator/c/genc.py pypy/dist/pypy/translator/c/stackless.py pypy/dist/pypy/translator/c/test/test_stackless.py Log: disabled graph optimization. changed interface to stackless. optimized stackless to do a full analysis which call-site really needs stackless support. This almost halves the speed difference between pypy-c-stackless and pypy-c. This is most of what can be done. There is a small opportunity to special-case tail recursive functions, but I doubt this is much fruit. Modified: pypy/dist/pypy/translator/c/genc.py ============================================================================== --- pypy/dist/pypy/translator/c/genc.py (original) +++ pypy/dist/pypy/translator/c/genc.py Mon Oct 31 21:37:54 2005 @@ -34,7 +34,7 @@ if self.stackless: from pypy.translator.c.stackless import StacklessData - db.stacklessdata = StacklessData() + db.stacklessdata = StacklessData(db) # we need a concrete gcpolicy to do this self.libraries += db.gcpolicy.gc_libraries() @@ -194,8 +194,8 @@ # ____________________________________________________________ -#SPLIT_CRITERIA = 32767 # enable to support VC++ 6.0 SPLIT_CRITERIA = 65535 # support VC++ 7.2 +#SPLIT_CRITERIA = 32767 # enable to support VC++ 6.0 MARKER = '/*/*/' # provide an easy way to split after generating @@ -225,9 +225,11 @@ self.funcnodes = funcnodes self.othernodes = othernodes self.path = path - return # the below is under development - graph = CallTree(self.funcnodes, self.database) - graph.simulate() + # disabled this for a while, does worsen things +# graph = CallTree(self.funcnodes, self.database) +# graph.simulate() +# graph.optimize() +# self.funcnodes = graph.ordered_funcnodes() def uniquecname(self, name): assert name.endswith('.c') @@ -273,7 +275,7 @@ # # All declarations # - database= self.database + database = self.database structdeflist = database.getstructdeflist() name = 'structdef.h' fi = self.makefile(name) Modified: pypy/dist/pypy/translator/c/stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/stackless.py (original) +++ pypy/dist/pypy/translator/c/stackless.py Mon Oct 31 21:37:54 2005 @@ -13,26 +13,86 @@ class StacklessData: - def __init__(self): + def __init__(self, database): self.frame_types = {} self.allsignatures = {} self.decode_table = [] + self.stackless_roots = {} # start the decoding table with entries for the functions that # are written manually in ll_stackless.h - self.registerunwindable('LL_stackless_stack_unwind', + def reg(name): + self.stackless_roots[name.lower()] = True + return name + + reg('LL_stack_unwind') + self.registerunwindable(reg('LL_stackless_stack_unwind'), lltype.FuncType([], lltype.Void), resume_points=1) - self.registerunwindable('LL_stackless_stack_frames_depth', + self.registerunwindable(reg('LL_stackless_stack_frames_depth'), lltype.FuncType([], lltype.Signed), resume_points=1) - self.registerunwindable('LL_stackless_switch', + self.registerunwindable(reg('LL_stackless_switch'), lltype.FuncType([Address], Address), resume_points=1) - self.registerunwindable('slp_end_of_yielding_function', + self.registerunwindable(reg('slp_end_of_yielding_function'), lltype.FuncType([], Address), resume_points=1) + self.can_reach_unwind = {} + self.database = database + self.count_calls = [0, 0] + + def unwind_reachable(self, func): + reach_dict = self.can_reach_unwind + if func not in reach_dict: + self.setup() + return reach_dict[func] + + def setup(self): + # to be called after database is complete, or we would + # not have valid externals info + self._compute_reach_unwind() + + def _compute_reach_unwind(self): + callers = {} + assert self.database.completed + translator = self.database.translator + here = len(translator.functions) + for func in translator.functions: + callers[func] = [] + for caller, callee in translator.complete_callgraph.values(): + callers[caller].append(callee) + # add newly generated ones + for func in translator.functions[here:]: + callers.setdefault(func, []) + # check all callees if they can reach unwind + seen = self.can_reach_unwind + + pending = {} + ext = self.database.externalfuncs + def check_unwind(func): + if func in pending: + ret = func not in ext + # typical pseudo-recursion of externals + # but true recursions do unwind + seen[func] = ret + return ret + pending[func] = func + for callee in callers[func]: + if callee in seen: + ret = seen[callee] + else: + ret = check_unwind(callee) + if ret: + break + else: + ret = func.__name__ in self.stackless_roots + del pending[func] + seen[func] = ret + return ret + [check_unwind(caller) for caller in callers if caller not in seen] + def registerunwindable(self, functionname, FUNC, resume_points): if resume_points >= 1: try: @@ -188,7 +248,22 @@ del self.resumeblocks def check_directcall_result(self, op, err, specialreturnvalue=None): - stacklessdata = self.db.stacklessdata + slp = self.db.stacklessdata + # don't generate code for calls that cannot unwind + if not specialreturnvalue: + need_stackless = slp.unwind_reachable(self.graph.func) + if need_stackless: + try: + callee = op.args[0].value._obj.graph.func + except AttributeError: + pass # assume we need it really + else: + need_stackless = slp.unwind_reachable(callee) + if not need_stackless: + slp.count_calls[False] += 1 + return (super(SlpFunctionCodeGenerator, self) + .check_directcall_result(op, err)) + slp.count_calls[True] += 1 block = self.currentblock curpos = block.operations.index(op) vars = list(variables_to_save_across_op(block, curpos)) @@ -206,7 +281,7 @@ variables_to_restore.append((v, '%s%d' % ( st.prefix, len(counts[st])))) counts[st].append('(%s)%s' % (st.ctype, varname)) - structname = stacklessdata.get_frame_type([len(counts[st]) for st in STATE_TYPES]) + structname = slp.get_frame_type([len(counts[st]) for st in STATE_TYPES]) # reorder the vars according to their type vars = sum([counts[st] for st in STATE_TYPES],[]) @@ -217,7 +292,7 @@ # The globally unique number for our state # is the total number of saved states so far - globalstatecounter = len(stacklessdata.decode_table) + len(self.savelines) + globalstatecounter = len(slp.decode_table) + len(self.savelines) arguments = ['%d' % globalstatecounter] + vars Modified: pypy/dist/pypy/translator/c/test/test_stackless.py ============================================================================== --- pypy/dist/pypy/translator/c/test/test_stackless.py (original) +++ pypy/dist/pypy/translator/c/test/test_stackless.py Mon Oct 31 21:37:54 2005 @@ -165,3 +165,28 @@ data = wrap_stackless_function(f) assert int(data.strip()) == 1234567 + +def test_yield_noswitch_frame(): + # this time we make sure that function 'g' does not + # need to switch and even does not need to be stackless + + def g(lst): + lst.append(2) + frametop_before_5 = yield_current_frame_to_caller() + lst.append(4) + return frametop_before_5 + + def f(): + lst = [1] + frametop_before_4 = g(lst) + lst.append(3) + frametop_after_return = frametop_before_4.switch() + lst.append(5) + assert frametop_after_return is None + n = 0 + for i in lst: + n = n*10 + i + return n + + data = wrap_stackless_function(f) + assert int(data.strip()) == 12345 From arigo at codespeak.net Mon Oct 31 21:41:29 2005 From: arigo at codespeak.net (arigo at codespeak.net) Date: Mon, 31 Oct 2005 21:41:29 +0100 (CET) Subject: [pypy-svn] r19304 - pypy/dist/pypy/bin Message-ID: <20051031204129.1742727B64@code1.codespeak.net> Author: arigo Date: Mon Oct 31 21:41:28 2005 New Revision: 19304 Modified: pypy/dist/pypy/bin/dotviewer.py Log: Better error message when running 'dotviewer.py' with no argument. Modified: pypy/dist/pypy/bin/dotviewer.py ============================================================================== --- pypy/dist/pypy/bin/dotviewer.py (original) +++ pypy/dist/pypy/bin/dotviewer.py Mon Oct 31 21:41:28 2005 @@ -17,7 +17,7 @@ In the first form, show the graph contained in a .dot file. In the other forms, connect to a graph server like -goal/translate_pypy +goal/translate_pypy. ''' % (sys.argv[0], sys.argv[0], sys.argv[0]) parser = optparse.OptionParser(usage=usage) @@ -28,7 +28,10 @@ if __name__ == '__main__': options, args = parser.parse_args() if len(args) != 1: - parser.error("too many options") + if args: + parser.error("too many arguments") + else: + parser.print_help() sys.exit(2) filename = args[0] if py.path.local(filename).check(): From pedronis at codespeak.net Mon Oct 31 21:49:06 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 21:49:06 +0100 (CET) Subject: [pypy-svn] r19305 - pypy/release/0.8.x/pypy/translator/goal Message-ID: <20051031204906.C187227B64@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 21:49:05 2005 New Revision: 19305 Removed: pypy/release/0.8.x/pypy/translator/goal/runtranslate.sh Modified: pypy/release/0.8.x/pypy/translator/goal/driver.py Log: merge 19301, 19302, move obsolote .sh script, fix typo Modified: pypy/release/0.8.x/pypy/translator/goal/driver.py ============================================================================== --- pypy/release/0.8.x/pypy/translator/goal/driver.py (original) +++ pypy/release/0.8.x/pypy/translator/goal/driver.py Mon Oct 31 21:49:05 2005 @@ -258,7 +258,7 @@ # task_llinterpret = taskdef(task_llinterpret, ['?backendopt', 'rtype'], - "LLInterpeting") + "LLInterpreting") def task_source_llvm(self): # xxx messy translator = self.translator From pedronis at codespeak.net Mon Oct 31 22:51:34 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 22:51:34 +0100 (CET) Subject: [pypy-svn] r19306 - in pypy/dist/pypy/translator: . test Message-ID: <20051031215134.E626227B64@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 22:51:33 2005 New Revision: 19306 Modified: pypy/dist/pypy/translator/geninterplevel.py pypy/dist/pypy/translator/test/test_geninterp.py Log: short-cut import sys|__builtin__|_codecs to space.builtinmodule(.) Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Mon Oct 31 22:51:33 2005 @@ -243,6 +243,14 @@ exv = space_shortcut fmt = "%(res)s = %(func)s(%(args)s)" else: + # import sys|__builtin__|_codecs avoid going through __import__ + if isinstance(v, Constant) and v.value is __builtin__.__import__: + name, glb, loc, frm_lst = op.args[1:] + if (isinstance(name, Constant) and name.value in ('sys', '__builtin__', '_codecs') and + isinstance(loc, Constant) and loc.value is None and + isinstance(frm_lst, Constant) and frm_lst.value is None): + return "%s = space.getbuiltinmodule(%r)" % (self.expr(op.result, localscope), + name.value) exv = self.expr(v, localscope) # default for a spacecall: fmt = "%(res)s = space.call_function(%(func)s, %(args)s)" 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 Oct 31 22:51:33 2005 @@ -40,7 +40,12 @@ snippet_ad = """if 1: def import_func(): import copy_reg - return copy_reg._reconstructor.func_code.co_name""" + return copy_reg._reconstructor.func_code.co_name + + def import_sys_func(): + import sys + return sys.__name__ +""" def setup_class(cls): # simply compile snippets just once @@ -78,6 +83,10 @@ import copy_reg impfunc = self.build_interpfunc(snippet.import_func) assert impfunc() == '_reconstructor' + + def test_import_sys(self): + impfunc = self.build_interpfunc(snippet.import_sys_func) + assert impfunc() == 'sys' def test_simple_func(self): cfunc = self.build_interpfunc(snippet.simple_func) From pedronis at codespeak.net Mon Oct 31 23:55:16 2005 From: pedronis at codespeak.net (pedronis at codespeak.net) Date: Mon, 31 Oct 2005 23:55:16 +0100 (CET) Subject: [pypy-svn] r19307 - pypy/dist/pypy/translator Message-ID: <20051031225516.5BD7427B64@code1.codespeak.net> Author: pedronis Date: Mon Oct 31 23:55:15 2005 New Revision: 19307 Modified: pypy/dist/pypy/translator/geninterplevel.py Log: oops, forgot to bump GI_VERSION Modified: pypy/dist/pypy/translator/geninterplevel.py ============================================================================== --- pypy/dist/pypy/translator/geninterplevel.py (original) +++ pypy/dist/pypy/translator/geninterplevel.py Mon Oct 31 23:55:15 2005 @@ -78,7 +78,7 @@ log = py.log.Producer("geninterp") py.log.setconsumer("geninterp", ansi_log) -GI_VERSION = '1.1.15' # bump this for substantial changes +GI_VERSION = '1.1.16' # bump this for substantial changes # ____________________________________________________________ try: